• C# Winform 界面线程的Invoke死锁,以及Application.DoEvent的问题


    1.对于非界面线程来说,Invoke是把一个操作丢到界面线程的队列里,然后阻塞,等到这个操作被界面线程完成后,才继续后续操作。也就是说,Invoke是同步的。

        问题来了,如果界面线程此时正在等待这个非界面线程的结束,然而这个非界面线程却又在等待界面线程执行完这个Invoke操作时,就会发生死锁。

    2.说白了,这个死锁问题,是Invoke执行机制产生的。

    3.解开这个死锁的方案也很简单。对于Invoke逻辑没有与界面线程逻辑有任何关系,则可以直接改造界面线程的等待非界面线程的结束操作:

        function ThreadUI()

        {

            while(true)

            {

                   if( Thread_New.ThreadState == Stopped )

                   {

                          break;

                   }

                   else

                   {

                          Sleep(10);

                   }

            }

        }

        改造成:

        function ThreadUI()

        {

            while(true)

            {

                   if( Thread_New.ThreadState == Stopped )

                   {

                          break;

                   }

                   else

                   {

                          Sleep(10);

                          Application.DoEvent();//这个语句,会让UI线程处理Invoke队列里的事情

                   }

            }

        }

       如果Invoke逻辑与界面线程的逻辑,有互相调用甚至加锁的关系,则需要先画图理清楚关系,然后再重新改造整个逻辑。此时,可能需要几个技术来辅助操作:

        1.新增线程或队列来分解事务

        2.把一些同步方法,改造成异步方法。改造成异步方法后,需要注意gc问题,以及错误处理问题。

        3.把一个大任务,按照执行顺序,分解为多个子任务,依次执行。

  • 相关阅读:
    tomcat启动报错host-manager does not exist
    jq对象,js对象,dom对象的转化
    Axure
    css盒子垂直居中
    数组去重个人总结的六种方式
    原生Ajax
    tp5总结(四)
    tp5总结(二)
    tp5总结(三)
    tp5总结(一)
  • 原文地址:https://www.cnblogs.com/xxxteam/p/3181203.html
Copyright © 2020-2023  润新知