[英]How to wait until method complete in C#?
I have this C# code, it works but it won't wait until the method completed 我有这个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();
}
How to wait until extract_group
method is done before moving to the next listBoxItem
? 在移动到下一个
listBoxItem
之前如何等待extract_group
方法完成?
I used t.join()
but it made the UI unresponsive. 我使用了
t.join()
但它使UI无响应。
Using async/await helps you to not block main thread. 使用异步/等待可以帮助您不阻塞主线程。
public async Task ExtractGroupAsync()
{
... (logic of the method)
... (you should use async methods here as well with await before executing those methods)
}
You execute this "ExtractGroup" task like: 您可以执行以下“ ExtractGroup”任务:
var example = await ExtractGroupAsync();
It makes GUI unresponsive, because you are on GUI thread. 由于您在GUI线程上,因此它使GUI无法响应。 Run whole code, in separate thread.
在单独的线程中运行整个代码。 Note: when you want to access GUI elements from another thread, you should use invoke, for example:
注意:当您要从另一个线程访问GUI元素时,应使用invoke,例如:
t.Invoke(() => t.Name = "Group Scrapper");
If you want to stick with Thread I recommend using a WaitHandle eg AsyncManualResetEvent Class . 如果您想坚持使用线程,我建议使用WaitHandle,例如AsyncManualResetEvent Class 。 This approach allows to make a thread wait without blocking CPU (eg spinlock).
这种方法可以使线程等待,而不会阻塞CPU(例如,自旋锁)。 Your provided example would become:
您提供的示例将变为:
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();
}
Another solution would be to go with the TPL and use Task instead of Thread : 另一个解决方案是使用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()));
}
}
The issue with your code sample is, that you are currently on the main thread, the UI thread. 代码示例的问题是,您当前位于主线程UI线程上。 Calling Thread.Join() does what you think it does: it blocks the waiting thread until the running thread completes.
调用Thread.Join()会执行您认为的工作:阻塞正在等待的线程,直到运行线程完成。 But as mentioned, the waiting thread is the UI thread, so the UI becomes unresponsive and can even deadlock in some scenario.
但是如前所述,等待线程是UI线程,因此UI在某些情况下会变得无响应甚至死锁。 When you use async/await your invocations become asynchronous and hence awaitable without blocking the UI thread.
当您使用async / await时,您的调用将变为异步,因此可以等待,而不会阻塞UI线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.