等待主线程停止,直到异步线程处理任务

时间:2010-12-03 04:56:16

标签: c# .net

假设我们有一个以下程序,在其Start方法中,它将一些长时间运行的任务委托给另一个线程。当调用Stop方法时,我需要确保工作线程完成执行当前任务并且不将它留在中间。如果它已经完成任务并处于睡眠状态,那么它可以立即停止。

请指导我如何做。

    static int itemsProcessed = 0;
    static Thread worker;
    static void Start()
    {
        var ts = new ThreadStart(Run);
        worker = new Thread(ts);
        worker.Start();
    }

    static void Stop()
    {
        //wait until the 'worker' completes processing the current item.
        Console.WriteLine("{0} Items Processed", itemsProcessed);
    }

    static void Run(object state)
    {
        while (true)
        {
            ALongRunningTask();
            itemsProcessed++;
            Thread.Sleep(1000);
        }
    }

2 个答案:

答案 0 :(得分:1)

假设您总是希望将长时间运行的任务线程作为一个整体来完成,您可以通过调用Thread.Join();

等待线程完成。

如果你想优雅地完成你的线程中的工作,你必须做一些消息传递,在最简单的情况下它可能只是一个布尔值 - 在你的情况下似乎只有一个线程,所以它可以是一个静态变量(尽可能简化)

static volatile bool processing = true;
static void Stop()
{
    processing = false;
    //wait until the 'worker' completes processing the current item.
    worker.Join();
    Console.WriteLine("{0} Items Processed", itemsProcessed);
}


static void Run(object state)
{
    while (proccessing)
    {
        ALongRunningTask();
        itemsProcessed++;
    }
}

答案 1 :(得分:1)

执行此操作的一种方法是使用volatile变量在两个线程之间进行通信。为此,创建一个“volatile bool isRunning;”。在Start中将值设置为true,然后在Run chage中将while循环设置为“while(isRunning)”。在stop中,将isRunning设置为false,然后调用worker.Join()。这将导致run方法在完成处理当前项时退出,Join将等待线程退出。

您需要做的最后一件事是以线程安全的方式访问itemsProcessed。在当前代码中,无法知道Stop是否看到itemsProcessed的最新值,因为它已从另一个线程更改。一种选择是为itemsProcessed创建一个锁并在Run中保持锁,并在Stop中的WriteLine语句之前获取锁。