我正在使用线程在Winform解决方案中执行多个任务,尝试在其工作时中止线程,但未中止,这是针对这种情况的解决方案吗?需要使线程顺利地中止/退出而没有任何问题!
还有关于如何使线程暂停/恢复的任何想法吗?
谢谢!
Thread CommentingThread;
CommentingThread = new Thread(async () =>
{
AddLog("Commenting process has been started!");
if (CommentBTN.InvokeRequired)
{
CommentBTN.Invoke((MethodInvoker)delegate () {
CommentBTN.Text = "Stop"; });
}
else
{
CommentBTN.Text = "Stop";
}
if (UrlListview.InvokeRequired)
{
if (UrlListview.InvokeRequired)
{
UrlListview.Invoke((MethodInvoker)async delegate ()
{
foreach (ListViewItem item in UrlListview.Items)
{
XtraMessageBox.Show(item.Text);
int timetodelay = RandomNumber.Next(int.Parse(CommentsMinDelayNumric.Value.ToString()), int.Parse(CommentsMaxDelayNumric.Value.ToString()));
await Task.Run(async () =>
{
await Task.Delay(timetodelay * 1000);
});
}
CommentBTN.Text = "Start";
AddLog("Commenting process has been finished sucessfully!");
});
}
}
else
{
foreach (ListViewItem item in UrlListview.Items)
{
XtraMessageBox.Show(item.Text);
int timetodelay = RandomNumber.Next(int.Parse(CommentsMinDelayNumric.Value.ToString()), int.Parse(CommentsMaxDelayNumric.Value.ToString()));
await Task.Run(async () =>
{
await Task.Delay(timetodelay * 1000 );
});
}
CommentBTN.Text = "Start";
AddLog("Commenting process has been finished sucessfully!");
}
#endregion
});
CommentingThread.Start();
if (CommentBTN.Text == "Stop")
{
CommentBTN.Text = "Start";
CommentingThread.Abort();
AddLog("Commenting process has been stopped!");
}
答案 0 :(得分:2)
首先,查看您的代码,如果UrlListview.Items
不包含任何元素,则线程可能立即停止。在这种情况下,您可能会丢失while循环。
关于停止线程的问题:
调用CommentingThread.Abort()
将引发一个ThreadAbortException
,这实际上使线程崩溃(有关更多信息,请参见the Microsoft Docs for more info。
要正常关闭线程,您应该声明CancellationTokenSource或一个布尔值,可以将其设置为true
(或false
,具体取决于您的实现),以通知线程它需要停止。这是一个示例:
var myThread_ctoks = new CancellationTokenSource();
Thread myThread = new Thread( async () =>
{
while (!myThread_ctoks.IsCancellationRequested) // simulate many long actions
{
await Task.Delay(TimeSpan.FromSeconds(2));
Console.WriteLine("Iteration finished!");
}
});
myThread.Start(); // start the thread
await Task.Delay(TimeSpan.FromMinutes(1)); // lets do some other work
myThread_ctoks.Cancel(); // and now shut down the thread
此线程每2秒检查一次是否需要关机(因为模拟操作花费的时间如此长)。一旦请求取消(myThread_ctoks.IsCancellationRequested设置为true),while条件将为false,因此线程将结束。 这样做的好处是,线程将以安全的,已定义的方式关闭,因为它实际上可以正常关闭并且不会崩溃。
关于如何暂停和恢复线程。您也可以使用变量来控制它,仅通过检查线程是否被允许工作即可。如果它应该暂停,那么您只需要等待一会儿即可。
也可以使用Thread.Suspend()
和Thread.Resume()
。但是,根据Microsoft,有可能在某些情况下可以锁定其他线程。此外,中断代码时,您不完全知道正在执行什么代码。这可能会导致进一步的意外行为。
这就是为什么我认为最好使用变量来控制线程行为。