簡體   English   中英

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

[英]Best way to wait for a background thread to finish processing in C#

我有一個后台主題。 如果后台線程忙,我想等待它完成其工作,然后繼續下一個請求。 我已通過以下方式實現它。 Process是后台線程的名稱。

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

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

這是最好的方式還是有其他方法來實現這種邏輯?

Thread類有一個名為Join的方法,它阻塞直到調用它的線程退出。
看看這里

根本不建議這樣做。 通過這種方式,您可以始終在不使用任何實際工作的情況下使用CPU。

如果要使用相同的方法,請在檢查線程是否處於活動狀態之前使用一些等待句柄或睡眠。

不過,我會建議您檢查文章為獲得在后台線程和不同的同步方式更好的理解。

要么

您還可以考慮使用ThreadPool來處理后台任務。 以下是微軟的一個例子

您可以使用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();
}

是否要等到某個任務完成后,使用Thread.Sleep(0)或Thread.Sleep(100)來避免燒掉100%的CPU內核只是為了等待一個標志被引發。

有一些事件和信號量的方法,但這個方法很簡單,不會有點傷害。

阻塞一個線程,等待另一個線程結束的方法稱為鎖定。 C#允許我們使用Monitor類或lock {}構造來鎖定代碼。 看看這個。

舉個例子:

 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
              } 
        }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM