如何在c#中正确关闭线程
本文关键字:线程 | 更新日期: 2023-09-27 18:24:59
我有一个在线程内部调用的方法。。
private System.Threading.Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private void DoWork()
{
while (!_shutdownEvent.WaitOne(0))
{
//Business logic
}
}
现在我开始线程。。
_thread = new Thread(DoWork);
_thread.Start();
现在,根据我的要求,我想关闭并重新启动线程。。对于关闭和重新启动,我正在尝试此代码。。
_shutdownEvent.Set(); // trigger the thread to stop
_thread.Join();
但我认为这不是关闭线程并重新启动它的正确方式。。
在我的情况下,请帮助我关闭并重新启动线程。提前谢谢。。
我建议您研究一下Task Parallel Library
,它可以对其执行进行细粒度控制,并通过CancellationToken
结构支持取消机制:
这里有一个例子:
var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
var task = Task.Factory.StartNew(() =>
{
// Were we already canceled?
ct.ThrowIfCancellationRequested();
bool moreToDo = true;
while (moreToDo)
{
// Poll on this property if you have to do
// other cleanup before throwing.
if (ct.IsCancellationRequested)
{
// Clean up here, then...
ct.ThrowIfCancellationRequested();
}
}
}, tokenSource.Token); // Pass same token to StartNew.
tokenSource.Cancel();
关于"重新启动线程",您不能重新启动给定的Task
。您可以看到它被取消了(一个任务包含一个Status
属性,一旦您取消,它将变成Canceled
),如果是这样,则执行一个新任务。
您应该尽量避免自己管理线程,并让CLR为您做到这一点。创建线程是一项代价高昂、容易出错的活动,最好不要管它。
FCL提供了可用于管理线程的类型。看看QueueUserWorkItem,它将执行回调中给定的一些代码。这在你只想说"去做某事",而不在乎它何时/是否完成,并且没有回报值的情况下效果很好。如果您想查看返回值,并知道某件事何时完成,请使用任务。
我强烈推荐Jeffrey Richer的CLR。它有一个关于线程和在.Net代码中使用它们的不同方法的优秀部分。
呃,试试现代的东西。
private Task DoWork(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// ... It would be nice if you could await something here.
}
return Task.FromResult(true);
}
然后,只发信号给CancellationToken
,
using (var cts = new CancellationTokenSource())
{
await Task.WhenAny(
DoWork(cts.Token),
SomeOtherWork())
cts.Cancel();
}
当前等待线程完成的方式看起来很好——线程在代码用完时会死亡,Join
确保它已经完成。
但是你不能重新启动一个线程,你必须创建一个新的线程。
我同意你可能想研究现有新技术的其他答案,它们允许更可读的代码。