簡體   English   中英

如何等待C#中的方法完成?

[英]How to wait until method complete in C#?

我有這個C#代碼,它可以工作,但是不會等到方法完成

foreach (var listBoxItem in visualListBox1.Items)
{
    lblCursor.Text = "Processing.. " + listBoxItem;
    Thread t = new Thread(() => extract_group(listBoxItem.ToString()));
    t.IsBackground = false; 
    t.Name = "Group Scrapper";
    t.Start();
}

在移動到下一個listBoxItem之前如何等待extract_group方法完成?

我使用了t.join()但它使UI無響應。

使用異步/等待可以幫助您不阻塞主線程。

public async Task ExtractGroupAsync()
{
   ... (logic of the method)
   ... (you should use async methods here as well with await before executing those methods)
}

您可以執行以下“ ExtractGroup”任務:

var example = await ExtractGroupAsync();

由於您在GUI線程上,因此它使GUI無法響應。 在單獨的線程中運行整個代碼。 注意:當您要從另一個線程訪問GUI元素時,應使用invoke,例如:

t.Invoke(() => t.Name = "Group Scrapper");

如果您想堅持使用線程,我建議使用WaitHandle,例如AsyncManualResetEvent Class 這種方法可以使線程等待,而不會阻塞CPU(例如,自旋鎖)。 您提供的示例將變為:

private static AsyncManualResetEvent mre = new AsyncManualResetEvent(false, true);
public async Task DoSomethingAsync(...)
{
  foreach (var listBoxItem in visualListBox1.Items)
  {
    lblCursor.Text = "Processing.. " + listBoxItem;
    Thread t = new Thread(() => ExtractGroup(listBoxItem.ToString()));
    t.IsBackground = false; 
    t.Name = "Group Scrapper";
    t.Start();

    // Wait for signal to proceed without blocking resources
    await mre.WaitAsync();
  }
}

private void ExtractGroup(string groupName)
{
  // Do something ...

  // Signal handle to release all waiting threads (makes them continue).
  // Subsequent calls to Set() or WaitOne() won't show effects until Rest() was called
  mre.Set();

  // Reset handle to make future call of WaitOne() wait again.
  mre.Reset();
}

另一個解決方案是使用TPL並使用Task而不是Thread

public async Task DoWorkAsync()
{
  foreach (var listBoxItem in visualListBox1.Items)
  {
    lblCursor.Text = "Processing.. " + listBoxItem;

    // Wait for signal to proceed without blocking resources
    await Task.Run(() => ExtractGroup(listBoxItem.ToString()));
  }
}  

代碼示例的問題是,您當前位於主線程UI線程上。 調用Thread.Join()會執行您認為的工作:阻塞正在等待的線程,直到運行線程完成。 但是如前所述,等待線程是UI線程,因此UI在某些情況下會變得無響應甚至死鎖。 當您使用async / await時,您的調用將變為異步,因此可以等待,而不會阻塞UI線程。

暫無
暫無

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

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