WinForms多线程问题 [英] WinForms multithreading issue

查看:90
本文介绍了WinForms多线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个线程在后台执行一些工作,并使用Invoke,BeginInvoke方法将更新传递给Form.线程是在显示表单后创建的,因此在那里没有问题.

Ive got a thread that does some work in the background and passes updates to the Form using the Invoke, BeginInvoke methods. The thread is created after the form is displayed so no issue there.

问题是如何正确关闭.我的工作线程有能力被要求退出,并且将在此之后不久(毫秒)退出.

The issue is how to correctly shutdown. My worker thread has the ability to be asked to exit, and will exit some time soon after that (miliseconds).

但是,如果首先关闭了窗体,则调用"内容将中断.我尝试将Thread.Join添加到窗体关闭事件中,但是这当然会导致死锁,甚至对于BeginInvoke也是如此,因为Thread.Join会阻塞该线程上的BeginInvoke ...

However if the form has closed first the Invoke stuff breaks. I tried adding a Thread.Join to the forms closing event, but of course this causes a deadlock, even for BeginInvoke since somhow a Thread.Join blocks a BeginInvoke on that thread...

关闭表单并干净地关闭其工作线程的正确方法是什么?

What is the correct way to close the form and shutdown its worker thread cleanly?

基本当前代码:

volatile bool abort;
void WorkerThread()
{
    while(!abort)DoStuffIncludingInvokesOnThisForm();
}
void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
    abort = true;
    workerThread.Join();//will deadlock with DoStuffIncludingInvokesOnThisForm
    //if get here before workerThread has exited, invokes will fail if workerthread is still in DoStuffIncludingInvokesOnThisForm
}

推荐答案

Form.Closing事件处理程序中,将Cancel属性设置为true,以暂时推迟关闭表单,直到工作线程完成.工作线程终止后,您可以在表单上重新发出Close命令.

From the Form.Closing event handler set the Cancel property to true to temporarily defer closing of the form until the worker thread has finished. Once the worker thread has terminated then you can reissue the Close command on the form.

public class MyForm : Form
{
  private volatile bool abort = false;
  private bool IsCloseRequested = false;
  private bool IsWorkerThreadComplete = false;

  private void MyForm_Closing(object sender, FormClosingEventArgs args)
  {
    if (!IsWorkerThreadComplete)
    {
      args.Cancel = true;
      IsCloseRequested = true;
      abort = true;
    }
  }

  void WorkerThread()
  {
    try
    {    
      while (!abort) DoStuffIncludingInvokesOnThisForm();
    }
    finally
    {
      OnWorkerThreadComplete();
    }
  }

  private void OnWorkerThreadComplete()
  {
    if (InvokeRequired) 
    {
      Invoke(((MethodInvoker)() => OnWorkerThreadComplete), null);
    }
    else
    {
      IsWorkerThreadComplete = true;
      if (IsCloseRequested) Close();
    }
  }
}

这篇关于WinForms多线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆