使用任务的经典永无止境的线程循环?
给定是一种非常常见的线程场景:
宣言
private Thread _thread; private bool _isRunning = false;
开始
_thread = new Thread(() => NeverEndingProc()); thread.Start();
方法
private void NeverEndingProc() { while(_isRunning) { do(); } }
可能在异步tcp侦听器中使用,它等待回调,直到它通过让线程用完而停止( _isRunning = false
)。
现在我想知道:是否有可能与Task
做同样的事情? 使用CancellationToken
? 或者仅针对预期结束和报告状态的程序的Task
?
你可以通过将NeverEndingProc
传递给NeverEndingProc
来实现这Task.Run
。
但是,function上有一个重要的区别:如果exception从裸Thread
的NeverEndingProc
传播出来,它将使进程崩溃。 如果它在Task
,它将引发TaskScheduler.UnobservedException
,然后被静默忽略(从.NET 4.5开始)。
也就是说,您可以探索其他选择。 例如, Reactive Extensions几乎消除了对“无限线程循环”的任何需求。
使用Task + CancellationToken的一个原因是使各个进程及其取消更加相互独立。 在您的示例中,请注意NeverEndingProc
如何直接引用同一类中的_isRunning
字段。 相反,您可以接受外部令牌:
开始:
public void StartNeverEndingProc(CancellationToken token) { Task.Factory.StartNew(() => NeverEndingProc(token), token); }
方法:
private void NeverEndingProc(CancellationToken token) { while (true) { token.ThrowIfCancellationRequested(); do(); } }
现在取消由调用者管理,并且可以应用于多个独立任务:
var instance = new YourClass(); var cts = new CancellationTokenSource(); instance.StartNeverEndingProc(cts.Token); // start your task StartOtherProc(cts.Token); // start another task cts.Cancel(); // cancel both