线程完成时通知,而不锁定调用线程 [英] Notify when thread is complete, without locking calling thread

查看:68
本文介绍了线程完成时通知,而不锁定调用线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发基于NET 3.5的旧版应用程序.这是我无法更改的约束. 我需要执行第二个线程来运行长时间运行的任务而不锁定UI.线程完成后,我需要以某种方式执行回调.

现在我尝试了这个伪代码:

Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
_thread.Join();
// execute finalizer

不锁定UI的第二个选项如下:

Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
while(_thread.IsAlive)
{
    Application.DoEvents();
    Thread.Sleep(100);
}
// execute finalizer

第二种解决方案当然不好,因为它会使UI过度收费. _thread完成后执行回调的正确方法是什么?另外,我怎么知道线程是被取消还是中止了?

* 注意:* 我不能使用BackgroundWorker,也不能使用Async库,我需要使用本机线程类.

解决方案

最简单的方法基本上是添加一个回调.您甚至可以仅使用多播委托的工作方式来做到这一点:

ThreadStart starter = myLongRunningTask;
starter += () => {
    // Do what you want in the callback
};
Thread thread = new Thread(starter) { IsBackground = true };
thread.Start();

这非常有用,如果线程中止或引发异常,则不会触发回调.您可以将其包装在具有多个回调或指定状态(异常,抛出异常等)并通过包装原始委托,使用try/阻止并适当执行回调.

除非您采取任何特殊措施,否则回调将在后台线程中执行,因此您将需要使用Control.BeginInvoke(或其他任何方式)将其编组回UI线程. /p>

I am working on a legacy application that is built on top of NET 3.5. This is a constraint that I can't change. I need to execute a second thread to run a long running task without locking the UI. When the thread is complete, somehow I need to execute a Callback.

Right now I tried this pseudo-code:

Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
_thread.Join();
// execute finalizer

The second option, which does not lock the UI, is the following:

Thread _thread = new Thread(myLongRunningTask) { IsBackground = True };
_tread.Start();
// wait until it's done
while(_thread.IsAlive)
{
    Application.DoEvents();
    Thread.Sleep(100);
}
// execute finalizer

Of course the second solution is not good cause it overcharge the UI. What is the correct way to execute a callback when a _thread is complete? Also, how do I know if the thread was cancelled or aborted?

*Note: * I can't use the BackgroundWorker and I can't use the Async library, I need to work with the native thread class.

解决方案

The simplest approach is to add a callback, basically. You can even do this just using the way that multicast delegates work:

ThreadStart starter = myLongRunningTask;
starter += () => {
    // Do what you want in the callback
};
Thread thread = new Thread(starter) { IsBackground = true };
thread.Start();

That's very vanilla, and the callback won't be fired if the thread is aborted or throws an exception. You could wrap it up in a class with either multiple callbacks, or a callback which specifies the status (aborted, threw an exception etc) and handles that by wrapping the original delegate, calling it in a method with a try/catch block and executing the callback appropriately.

Unless you take any special action, the callback will be executed in the background thread, so you'll need to use Control.BeginInvoke (or whatever) to marshal back to the UI thread.

这篇关于线程完成时通知,而不锁定调用线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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