在C#Winform解决方案中使用线程,但不会终止

时间:2018-10-13 22:08:06

标签: c# multithreading winforms

我正在使用线程在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!");


    }

1 个答案:

答案 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,有可能在某些情况下可以锁定其他线程。此外,中断代码时,您不完全知道正在执行什么代码。这可能会导致进一步的意外行为。 这就是为什么我认为最好使用变量来控制线程行为。