C# 对多个任务使用async/await时UI不更新

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

我正在编写一些示例代码,演示我所做的演示的async/await,由于某些原因,标签内容没有按预期更新

    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更新,如果您期望/意味着this
this.AsyncAwaitButton.IsEnabled=true
要执行,必须在所有任务完成后才能执行。@CodingYoshi它指的是标签内容的更新:
this.asyncwaitdata.content=[…]
为什么要在
选择中执行工作?它是为了查询而不是为了做工作。不管怎样,你有这样的代码:
ReadTextAsync
,你需要阅读,这样你才能真正理解发生了什么。另外,对于介绍async/await概念的演示文稿,我不会编写所有代码并尽量使其简单。是否有任何测试可以确认这是文件系统问题?我在Windows7机器上运行这些示例,这台机器应该完全支持异步I/O,但快速搜索发现异步操作可以出于各种原因同步执行。由于这是一个演示,我想我可以使用
Task.Delay()
@KennethCochran模拟异步I/O。最简单的测试方法是在等待返回的
任务之前查看它,并检查它是否已经完成。如果是,您知道它是同步运行的。