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

时间:2018-05-19 07:56:33

标签: 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();
}

如何等到extract_group方法完成后再转到下一个listBoxItem

我使用t.join(),但它使用户界面无法响应。

3 个答案:

答案 0 :(得分:1)

使用async / await可以帮助您不阻止主线程。

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();

答案 1 :(得分:0)

它使GUI无响应,因为您使用的是GUI线程。在单独的线程中运行整个代码。 注意:当您想要从另一个线程访问GUI元素时,您应该使用invoke,例如:

MYFILE~1.TXT

答案 2 :(得分:0)

如果你想坚持使用线程,我建议使用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 而不是线程

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线程的情况下等待。