我有这个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()
,但它使用户界面无法响应。
答案 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();
}
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线程的情况下等待。