在C#中等待后台线程完成处理的最佳方法

4

我有一个后台线程。如果后台线程正在忙碌,我希望等待它完成工作然后继续处理下一个请求。我已经按照以下方式实现了此功能。Process是后台线程的名称。

 if (process.IsBusy)
 {
     do
     {
         isProcessBusy = process.IsBusy;
     } while (isProcessBusy == false);

     SetIsDirty(status, GetContext());
 }
 else
 {
     SetIsDirty(status, GetContext());
 }

这是最佳实现方式,还是有其他方法来实现这种逻辑?


这不是最好的方法,因为:a)它会占用CPU;b)它可以写成while(!process.IsBusy);。无论如何,您可以加入线程或使用锁/信号量。 - khachik
5个回答

6

Thread类有一个名为Join的方法,该方法会阻塞直到调用该方法的线程退出。
请参考这里


2

您可以使用 AutoResetEvent 来实现:

示例:

AutoResetEvent resetEvent = new AutoResetEvent(false);

private void StartProcess()
{
    new Thread(DoProcess).Start();
}

private void DoProcess()
{
    List<String> list = new List<String>() { 
        "Value 1",
        "Value 2",
        "Value 3",
        "Value 4",
        "Value 5",
    };

    foreach (String item in list)
    {
        process.RunWorkerAsync(item);

        if (!resetEvent.WaitOne())
        {
            // Some exception
            break;
        }
        resetEvent.Reset();
    }
}

private void process_DoWork(object sender, DoWorkEventArgs e)
{
    Debug.WriteLine(e.Argument.ToString());
    Thread.Sleep(1000);
}

private void process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    resetEvent.Set();
}

2
这种方式并不被推荐。这样做会让你的CPU一直处于空闲状态而没有实际工作。
如果你想使用相同的方法,可以在检查线程是否活动之前使用一些等待句柄或休眠。
然而,我建议查看这篇文章,以更好地了解后台线程和不同的同步方法。
或者,你也可以考虑使用ThreadPool来处理后台任务。这里有一个来自微软的示例

0
阻塞一个线程,等待另一个线程结束的方法称为锁定。C#允许我们使用Monitor类或lock{}结构锁定代码。请查看this.
例如:
 Class1()
            {
                  // construct two threads for our demonstration;
                  Thread thread1 = new Thread(new ThreadStart(DisplayThread1));
                  Thread thread2 = new Thread(new ThreadStart(DisplayThread2));

                  // start them
                  thread1.Start();
                  thread2.Start();
            }

        void DisplayThread1()
        {
              while (_stopThreads == false)
              {
                  // lock on the current instance of the class for thread #1
                    lock (this)
                    {
                          Console.WriteLine("Display Thread 1");
                          _threadOutput = "Hello Thread1";
                          Thread.Sleep(1000);  // simulate a lot of processing
                          // tell the user what thread we are in thread #1
                          Console.WriteLine("Thread 1 Output --> {0}", _threadOutput);
                    } // lock released  for thread #1 here
              } 
        }

        void DisplayThread2()
        {
              while (_stopThreads == false)
              {

                  // lock on the current instance of the class for thread #2
                    lock (this)
                    {
                          Console.WriteLine("Display Thread 2");
                          _threadOutput = "Hello Thread2";
                          Thread.Sleep(1000);  // simulate a lot of processing
                          // tell the user what thread we are in thread #1
                          Console.WriteLine("Thread 2 Output --> {0}", _threadOutput);
                    }  // lock released  for thread #2 here
              } 
        }

}


0
如果你想等待某个任务完成,可以使用Thread.Sleep(0)或Thread.Sleep(100),以避免为等待一个标志而烧掉100%的CPU核心。
虽然有一些带有事件和信号量的方法,但这种方法简单易行,不会有任何问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接