C# 对多个任务使用async/await时UI不更新
我正在编写一些示例代码,演示我所做的演示的async/await,由于某些原因,标签内容没有按预期更新C# 对多个任务使用async/await时UI不更新,c#,user-interface,async-await,C#,User Interface,Async Await,我正在编写一些示例代码,演示我所做的演示的async/await,由于某些原因,标签内容没有按预期更新 private async void AsyncAwaitButton_Click(object sender, RoutedEventArgs e) { this.AsyncAwaitButton.IsEnabled = false; var start = DateTime.Now; IList<Task> tas
private async void AsyncAwaitButton_Click(object sender, RoutedEventArgs e)
{
this.AsyncAwaitButton.IsEnabled = false;
var start = DateTime.Now;
IList<Task> tasks = new List<Task>();
for (int i = 0; i < int.Parse(this.IterationsTextBox.Text); i++)
{
tasks.Add(this.ReadTextAsync(this.dataPath));
}
await Task.WhenAll(
tasks.Select(
async x =>
{
this.AsyncAwaitData.Content = $"Elapsed time: {DateTime.Now - start}";
await x;
}));
this.AsyncAwaitButton.IsEnabled = true;
}
private async Task<string> ReadTextAsync(string filePath)
{
using (
var sourceStream = new FileStream(
filePath,
FileMode.Open,
FileAccess.Read,
FileShare.Read,
bufferSize: 4096,
useAsync: true))
{
var sb = new StringBuilder();
var buffer = new byte[0x1000];
int numRead;
while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
var text = Encoding.UTF8.GetString(buffer, 0, numRead);
sb.Append(text);
}
return sb.ToString();
}
}
private async void asyncwaitbutton\u单击(对象发送方,RoutedEventArgs e)
{
this.asyncWaitButton.IsEnabled=false;
var start=DateTime.Now;
IList tasks=新列表();
for(int i=0;i
{
this.AsyncAwaitData.Content=$“运行时间:{DateTime.Now-start}”;
等待x;
}));
this.asyncWaitButton.IsEnabled=true;
}
专用异步任务ReadTextAsync(字符串文件路径)
{
使用(
var sourceStream=新文件流(
文件路径,
FileMode.Open,
FileAccess.Read,
文件共享,
缓冲区大小:4096,
useAsync:true)
{
var sb=新的StringBuilder();
var buffer=新字节[0x1000];
国际货币联盟;
while((numRead=wait sourceStream.ReadAsync(buffer,0,buffer.Length))!=0)
{
var text=Encoding.UTF8.GetString(缓冲区,0,numRead);
附加(正文);
}
使某人返回字符串();
}
}
现在,如果我正确理解了自己的代码,Select
语句正在创建一个IEnumerable
,其中每个任务都在等待前面的for
循环填充的tasks
变量中的相应任务。然后将该IEnumerable
传递给Task.whalll
我希望由于等待x代码>生成线程后,UI将有足够的机会重新绘制以反映更改的标签内容,但由于某些原因,它仅在所有任务完成后更新。即使添加一个Task.Delay(1000)
似乎也不会影响行为
我缺少什么?代码运行在不支持异步文件操作的操作系统上,因此FileStream.ReadAsync
同步运行,尽管名称中有Async
,并返回任务。由于该方法是同步运行的,因此等待它的所有方法也都是同步运行的,这就是您显示的所有代码
由于您需要异步运行此操作,为了不阻塞UI线程,您别无选择,只能使用任务。运行调用ReadTextAsync
(或ReadAsync
,如果愿意),以确保操作实际异步运行。您可以发布ReadTextAsync
的代码吗?是的,对不起。我已经更新了代码。通过ui更新,如果您期望/意味着thisthis.AsyncAwaitButton.IsEnabled=true
要执行,必须在所有任务完成后才能执行。@CodingYoshi它指的是标签内容的更新:this.asyncwaitdata.content=[…]
为什么要在选择中执行工作?它是为了查询而不是为了做工作。不管怎样,你有这样的代码:ReadTextAsync
,你需要阅读,这样你才能真正理解发生了什么。另外,对于介绍async/await概念的演示文稿,我不会编写所有代码并尽量使其简单。是否有任何测试可以确认这是文件系统问题?我在Windows7机器上运行这些示例,这台机器应该完全支持异步I/O,但快速搜索发现异步操作可以出于各种原因同步执行。由于这是一个演示,我想我可以使用Task.Delay()
@KennethCochran模拟异步I/O。最简单的测试方法是在等待返回的任务之前查看它,并检查它是否已经完成。如果是,您知道它是同步运行的。