2 huangchao2011 huangchao2011 于 2017.01.04 16:11 提问

C#并行任务出现卡死的问题

我想实现的结果很简单,就是用并行的方式去为2个控件赋值,但是结果是窗体会假死,看起来是死锁的样子,不懂为什么,谁能给讲解讲解一下。
代码:

 private void button4_Click(object sender, EventArgs e)
        {
            Parallel.Invoke(
               SetLable1Text,
               SetLable2Text
                );
        }

        void SetLable1Text()
        {
            label1.Invoke(new Action(() => {
                label1.Text = "正在执行...";
                Thread.Sleep(TimeSpan.FromSeconds(3));
                label1.Text = "执行完毕";
            }));
        }

        void SetLable2Text()
        {
            label2.Invoke(new Action(() =>
            {
                label2.Text = "正在执行...";
                Thread.Sleep(TimeSpan.FromSeconds(2));
                label2.Text = "执行完毕";
            }));
        }

2个回答

qq_21020791
qq_21020791   2017.01.04 16:46

Thread.Sleep()阻塞了GUI线程,所以窗体假死了。

u012046379
u012046379   2017.01.05 12:30

你 Parallel.Invoke 在主线程中调用的,要等到invoke参数里所有任务执行完成后 主线程才返回。经过测试,invoke参数里面的第一个任务始终是在主线程中执行的,所以修改UI能成功,而后面的任务在其他线程执行。当第二个任务开始的时候,在调用label2.Invoke的时候 是子线程请求主线程更新UI,但是主线程现在没有返回只能继续等待。主线程也在等待所有任务完成后返回(主线程等待任务二完成后返回,任务二在等待主线程完成后更新UI所以任务二永远没法完成)造成死锁
解决办法:
一.都用BeginInvoke

  void SetLable2Text()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":"+Thread.CurrentThread.ThreadState.ToString());
                label2.Invoke(new Action(() =>
                {

                // Thread.Sleep(TimeSpan.FromSeconds(2));
                label2.Text = "执行完毕";
                    Console.WriteLine("Method=2, Thread={0}", Thread.CurrentThread.ManagedThreadId);


                }));
            }

二. 把Parallel.Invoke放到子线程
ThreadPool.QueueUserWorkItem(w =>
{
tThread.ThreadState.ToString());
Parallel.Invoke(
()=> { Console.WriteLine("Lable1:coutn:0" + "," + Thread.CurrentThread.ManagedThreadId + ":" + Thread.CurrentThread.ThreadState.ToString()); },
SetLable2Text,
SetLable1Text
);
});

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!