zoukankan      html  css  js  c++  java
  • 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.把一个大任务,按照执行顺序,分解为多个子任务,依次执行。

  • 相关阅读:
    Sql Server中暂停命令
    优化SQL Sever查询语句的几个要点
    SQL Server 常用日期查询语句
    Android开发环境配置
    java实验报告(实验一)
    java实验报告(实验二)
    学习java的一点体会
    [已解决]求助:vs2003用代码实现excel的设置
    关于webform信息提示框
    DataGrid按钮事件的触发
  • 原文地址:https://www.cnblogs.com/xxxteam/p/3181203.html
Copyright © 2011-2022 走看看