weixin_56459510 2024-04-04 21:18 采纳率: 33.3%
浏览 17
已结题

c# 使用 Task task = Task.Run(() =>),执行代码后出结果后,主窗体(也就是上一级窗体)出错

c# 使用 Task task = Task.Run(() =>),执行代码后出结果后,主窗体(也就是上一级窗体)出错
错误提示如下图

img

img


Frm_JmMll frmJmMll = new Frm_JmMll(); //f4.StartPosition = FormStartPosition.CenterScreen;
            frmJmMll.StartPosition = FormStartPosition.CenterScreen;
            frmJmMll.ShowDialog();

代码如图

img

 Task task = Task.Run(() =>
            {
                data_JmMll = dd.OpenFileWS(tbpathE.Text);//调用打开,读取用户打开的txt文件,赋值给data_JmMll集合

                DataTable dt_JmMll = new DataTable("Number");
                DataColumn dc00 = dt_JmMll.Columns.Add("序号", typeof(string));
                DataColumn dc000 = dt_JmMll.Columns.Add("供应商", typeof(string));
                DataColumn dc1 = dt_JmMll.Columns.Add("条码", typeof(string));
                DataColumn dc2 = dt_JmMll.Columns.Add("名称", typeof(string));
                DataColumn dc5 = dt_JmMll.Columns.Add("类别", typeof(string));
                DataColumn dc3 = dt_JmMll.Columns.Add("进价", typeof(string));
                DataColumn dc4 = dt_JmMll.Columns.Add("售价", typeof(string));
                DataColumn dc6 = dt_JmMll.Columns.Add("库存", typeof(string));

                int Itbtrue = 0;int Itbgood = 0;int k = 1;
                 InsertEvent += new Insert(BsMerge_InsertEvent);//使用事件方法,同步显示数据 避免假死出现
                SetProgressbar(0, data_JmMll.Count);

                for (int j = 0; j < data_JmMll.Count; j++)
                {
                    Gressbar(j);//调用方法,赋值给MgBar1

                    string aa = data_JmMll[j].ToString().Replace("\t", "").Replace(" ", "").Trim();
                    DataTable dt1 = Stock.CPublic.DT("SELECT  t_goods.vendorno,t_goods.barcode,t_goods.itemname,s_class.descr as 类别,t_goods.purprice,t_goods.saleprice,t_depot_h.itemqty as 库存 FROM t_depot_h,t_goods,s_class WHERE  ( t_depot_h.itemno = t_goods.itemno ) and ( s_class.classcode = t_goods.classcode ) and t_goods.barcode='" + aa + "'  ");
                    if (dt1.Rows.Count > 0)//Rows.Count =0 代表数据库没记录即是新品
                    {
                        DataRow dr;
                        dr = dt_JmMll.NewRow();
                        dr["序号"] = j + 1;//使用j 保留txt对应的序号
                        dr["条码"] = aa;
                        dr["供应商"] = dt1.Rows[0][0].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dr["名称"] = dt1.Rows[0][2].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dr["类别"] = dt1.Rows[0][3].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dr["进价"] = dt1.Rows[0][4].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dr["售价"] = dt1.Rows[0][5].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dr["库存"] = dt1.Rows[0][6].ToString().Replace("\t", "").Replace(" ", "").Trim();
                        dt_JmMll.Rows.Add(dr);
                        Itbtrue++;
                        k++;
                    }
                    Itbgood++;
                    if (InsertEvent != null) { BsMerge_InsertEvent(null, j + 1, data_JmMll.Count); }//使用事件,动态显示数据,且窗口不假死
                }
                dataGridView1.DataSource = dt_JmMll;

            });

  • 写回答

4条回答 默认 最新

  • 关注

    晚上好🌙🌙🌙
    本答案参考ChatGPT-3.5

    根据您的描述,问题可能是因为在子线程(使用Task.Run方法)中更新了主窗体的UI,而不是在主线程中进行UI操作。这可能会导致线程间的冲突,从而导致主窗体出错。

    解决这个问题的方式如下:

    1. 使用Invoke方法将主窗体操作调度到主线程中执行。在Task.Run中的代码块中,使用Invoke方法来更新主窗体的UI。

    修改代码如下:

    Task task = Task.Run(() =>
    {
        // your code here
    
        dataGridView1.Invoke(new Action(() =>
        {
            dataGridView1.DataSource = dt_JmMll;
        }));
    });
    
    1. 为了避免线程冲突,可以将需要更新UI的部分移动到主线程中执行。可以将数据处理和UI更新分离,将数据处理的部分放在子线程中执行,然后在子线程执行完毕后,在主线程中进行UI的更新。

    修改代码如下:

    Task task = Task.Run(() =>
    {
        // your code here
    
        return dt_JmMll;
    }).ContinueWith(result =>
    {
        dataGridView1.DataSource = result.Result;
    }, TaskScheduler.FromCurrentSynchronizationContext());
    

    这样子线程中的代码执行完毕后,任务会自动切换到主线程中,然后在主线程中更新UI。

    在这两种方式中,都使用了TaskScheduler.FromCurrentSynchronizationContext()来获取主线程的同步上下文,以确保UI更新在主线程中执行。

    希望以上解决方案能够帮助到您解决问题。如果您仍然遇到困难,请提供更多的错误信息和相关代码,以便我能够更好地帮助您。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月12日
  • 已采纳回答 4月4日
  • 创建了问题 4月4日

悬赏问题

  • ¥15 pcl运行在qt msvc2019环境运行效率低于visual studio 2019
  • ¥15 MAUI,Zxing扫码,华为手机没反应。可提高悬赏
  • ¥15 python运行报错 ModuleNotFoundError: No module named 'torch'
  • ¥100 华为手机私有App后台保活
  • ¥15 sqlserver中加密的密码字段查询问题
  • ¥20 有谁能看看我coe文件到底哪儿有问题吗?
  • ¥20 我的这个coe文件到底哪儿出问题了
  • ¥15 matlab使用自定义函数时一直报错输入参数过多
  • ¥15 设计一个温度闭环控制系统
  • ¥100 rtmpose姿态评估