我认为以下问题很少见。但由于我不知道如何寻找正确的答案,所以我仍然坚持下去。
我在表单中有一个标签,我想在调用另一个作业之前显示一些内容:
private void btnLoadEvent_Click(object sender, EventArgs e)
{
lbStatus.Text = "Loading... ";
load();
}
private void load()
{
Thread.Sleep(5000);
lbStatus.Text = "Done";
}
在load()完成之前,标签不会显示任何内容。
然后我改变了程序usnig async / await:
private async void btnLoadEvent_Click(object sender, EventArgs e)
{
lbStatus.Text = "Loading... ";
await load();
}
private async Task load()
{
Thread.Sleep(5000);
lbStatus.Text = "Done";
}
它不会改变任何东西。有没有人有任何想法?
2014年4月3日:
作为一个说明,我想我已经弄明白async / await是如何工作的。为了避免误导任何可能的读者,我列出了我的最终解决方案如下:
private async void btnLoadEvent_Click(object sender, EventArgs e)
{
lbStatus.Text = "Loading... ";
string content = await loadAsync();
}
private async Task<string> loadAsync()
{
using (WebClient webClient = new WebClient())
{
string json = await webClient.DownloadStringTaskAsync(
"http://api.openweathermap.org/data/2.5/weather?q=Taipei,tw");
lbStatus.Text = "Done";
return json;
}
}
在实践中,为了满足解耦原则,“lbStatus.Text = ...”可以更好地从loadAsync()移动到btnLoadEvent_Click(),尽管它工作正常。
感谢所有帮助过的人。
答案 0 :(得分:3)
你并没有真正去异步。 Thread.Sleep是阻塞的,因为你的异步函数永远不会产生它仍然会阻塞调用站点。请改用await Task.Delay(...
。
private void btnLoadEvent_Click(object sender, EventArgs e)
{
lbStatus.Text = "Loading... ";
load();
}
private async Task load()
{
await Task.Delay(5000);
lbStatus.Text = "Done";
}
答案 1 :(得分:0)
尝试使用BackgroundWorker。在执行BackgroundWorker的RunWorkerAsync
方法之前,将label.Text设置为Loading。在Do_Work
事件中处理您的内容(例如Thread.Sleep(5000))并更改RunWorkerCompleted
事件中标签的状态。访问this link查看示例。
答案 2 :(得分:0)
您需要使用BackgroundWorker。这样的事情。
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Loading";
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
load();
}
private void load()
{
System.Threading.Thread.Sleep(1000);
if(InvokeRequired)
this.Invoke(new Action(()=>label1.Text = "Done"));
}