Jam*_*mes 0 .net c# user-interface async-await
我有一个按钮,当我点击它时,我希望它用值更新UI
这是我的按钮
private async void Button_Click(object sender, RoutedEventArgs e)
{
await DoItAsync();
}
Run Code Online (Sandbox Code Playgroud)
这就是DoIt!
public async Task DoSomethingAsync()
{
await Task.Run(()=>{
for(int i = 0; i < 2000; i++)
{
//labelName.Content = i.ToString();
Console.WriteLine(i);
}
});
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我运行上面的代码,单击我的按钮,调用DoItAysnc并在控制台中显示所有数字.
如果我不发表评论
labelName.Content = i.ToString();
Run Code Online (Sandbox Code Playgroud)
我得到一个异常,事实如下:调用线程无法访问此对象,因为另一个线程拥有它.
我知道Async和await不会为你解决线程问题,但我确实认为这会有效.我想知道如何使其工作,以便为每个i值更新UI,而不会使UI无响应.
对此有任何好的资源也会有所帮助.
各种各样的问候
在这种特殊情况下,你所做的一切似乎都是尽可能快地在标签上计算到2000.这不太可能是您的实际用例.
如果您想在多个不同的异步操作(例如,等待一段时间)中更新UI,那么您可以构建代码,如下所示:
private async void Button_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 2000; i++)
{
await Task.Delay(TimeSpan.FromSeconds(1));
labelName.Content = i.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在概念上正在做的是使用长时间运行的非UI操作的进度来更新UI,那么Progress该类旨在专门处理:
private async void Button_Click(object sender, RoutedEventArgs e)
{
Progress<int> progress = new Progress<int>(
i => labelName.Content = i.ToString());
await Task.Run(() => DoWork(progress));
}
private void DoWork(IProgress<int> progress)
{
for (int i = 0; i < 2000; i++)
{
//Do Stuff
progress.Report(i);
}
}
Run Code Online (Sandbox Code Playgroud)
通常,如果您可以将问题分解为一组小的异步操作,其中UI在每个操作之间进行更新,则第一个选项是有意义的.如果存在单个长的非UI操作而不能轻易地分解为较小的操作,则完成第二种方法.
| 归档时间: |
|
| 查看次数: |
2673 次 |
| 最近记录: |