c#多线程同步之EventWaitHandle的应用

      最近在研究前辈写的winform代码,其中有一个功能,前辈用了EventWaitHandle。初读代码,有点不理解,慢慢想来,还是可以理解的。这个功能,就是执行某项比较耗时的任务,需要打开旋转图标,等任务执行完成后,再关闭旋转图标。这是程序主体框架:

 1  public void ImportFile(List<string> files)
 2         {
 3             bool state = true;
 4             EventWaitHandle wait = new EventWaitHandle(false, EventResetMode.ManualReset);
 5             EventWaitHandle loadWait = new EventWaitHandle(false, EventResetMode.ManualReset);
 6 
 7             Thread thread = new Thread(delegate(object obj)
 8                {
 9                    loadWait.WaitOne();
10                    EventWaitHandle waitHandle = obj as EventWaitHandle;
11 
12                    try
13                    {
14                        //执行比较耗时的任务
15                    }
16                    catch
17                    {
18                        state = false;
19                    }
20                    waitHandle.Set();
21                });
22 
23             thread.Start(wait);
24             new OperationTip().ShowWait(wait, loadWait, MainForm._MainForm);
25 
26             if (!state)
27             {
28                 new ServerErrorInformation().ShowDialog(MainForm._MainForm);
29                 return;
30             }
31         }

解释:线程(给个名称:TaskThread)启动后(23行),被阻塞了(第9行loadWait.Wait() )。那什么时候解除阻塞呢?24行实例化了一个OperationTip对象,而且调用了ShowWait方法,我想秘密就在这个类里面:

    public partial class OperationTip : Form
    {
        public delegate void CloseThis();
        EventWaitHandle loadWait = null;public OperationTip()
        {
            InitializeComponent();
            this.Icon = Resources.NoteFirst;
            this.ptbMain.Image = Resources.SystemProcess_1;
            this.ShowInTaskbar = false;
        }private void OperationTip_Load(object sender, EventArgs e)
        {
            if (point.X == 0 && point.Y == 0)
            {
                this.StartPosition = FormStartPosition.CenterParent;
            }
            else
            {
                this.Location = new Point(point.X, point.Y);
            }
            if (loadWait != null)
                loadWait.Set();
        }

 public void ShowWait(EventWaitHandle wait, EventWaitHandle loadWait, IWin32Window window)
        {
            this.loadWait = loadWait;
            ThreadPool.QueueUserWorkItem(delegate
            {
                wait.WaitOne();
                if (this.InvokeRequired)
                {
                    this.Invoke(new CloseThis(CloseThisForm));
                }
                else
                {
                    CloseThisForm();
                }
            });
            this.ShowDialog(window);
        }
     public void CloseThisForm()
        {
            this.Close();
        }
    }

      很有意思的是 ShowWait方法里,又开启了一个线程(起个名称:closeThread),这个线程专门负责关闭当前的旋转图标(OperationTip 窗体,整个窗体看起来就是一个旋转图标)。此线程目前被阻塞,ShowDialog方法调用后,OperationTip_Load方法才开始执行,此时 loadWait.Set(),让TaskThread 才开始执行,等执行完了,第20行 waitHandle.Set()方法的执行,它解除了closeThread线程的阻塞,让closeThread线程继续运行,那么旋转图标就被关闭了。

 

posted @ 2017-11-27 18:41  micDavid  阅读(383)  评论(0编辑  收藏  举报