• C#.NET WinForm 多个子Task嵌套 Task.WaitAll 阻塞UI线程


     C#.NET WinForm 多个子Task(子线程)嵌套  Task.WaitAll 阻塞UI线程 (界面)

    情况:

    DoIt()方法内,开了2个Task 执行任务,子任务中会更新UI。

    DoIt() 是同步(UI线程)。

    DoIt()部分代码:

                    var myTask = Task.Run(() =>
                            {
                                DoIt2(lstBatch1, 1);
                            });
                    Task.WaitAll(myTask);
    
                    curMsg = NS() + " batch 2 ";
                    InserLbxMsg(curMsg);
    
                    myTask = Task.Run(() =>
                    {
                        DoIt2(lstBatch2, 2);
                    });
                    Task.WaitAll(myTask);

    DoIt2 方法内会更新UI ,InvokeInserLbxMsg(curMsg); 。

    /// <summary>
            /// BeginInvoke
            /// </summary>
            /// <param name="curMsg"></param>
            void InvokeInserLbxMsg(string curMsg)
            {
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new MethodInvoker(() =>
                    {
                        lbxMsg.Items.Insert(0, curMsg);
                    }));
                }
                else
                {
                    lbxMsg.Items.Insert(0, curMsg);
                }
            }

    结果导致 DoIt2 更新UI失败,并阻塞了UI线程 。

    解决方法:

    DoIt 方法内2个Task.WaitAll,换成 ContinueWith:

    var myTask = Task.Run(() =>
                            {
                                DoIt2(lstBatch1, 1);
                            });
                    myTask.ContinueWith(t =>
                    {
                        DoIt2(lstBatch2, 2);
                        InvokeInserLbxMsg("完成");
                    });

    重点: UI线程的方法(同步),不要用Task.WaitAll。

    --

  • 相关阅读:
    ACE 的一些词汇
    odbc连接不上,初步猜想是myodbc安装有问题
    1分钟 当数据库管理员
    硬件申请
    编译删除
    ASP.NET之数据绑定
    发布、订阅、复制、同步SQL Server 2000 数据库
    SQL——添加约束的语句
    SQL——规则
    十大著名黑客—— 凯文米特尼克
  • 原文地址:https://www.cnblogs.com/runliuv/p/16267704.html
Copyright © 2020-2023  润新知