我正在编写一些示例代码,演示异步/等待演示文稿我给出了由于某种原因标签内容未按预期更新。
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();
}
}
现在,如果我正确理解自己的代码,Select
语句正在创建IEnumerable<Task>
,其中每个任务都在等待前面{{1}填充的tasks
变量中的相应任务循环。然后将此for
传递给IEnumerable<Task>
。
我希望由于Task.WhenAll
产生线程,UI将有足够的机会重新绘制以反映更改的标签内容,但由于某种原因,它只在所有任务完成后才更新。即使添加await x;
似乎也不会影响行为。
我错过了什么?
答案 0 :(得分:-3)
代码在不支持异步文件操作的操作系统上运行,因此FileStream.ReadAsync
同步运行,尽管名称中包含Async
并返回Task
。由于该方法正在同步运行,所以等待它的所有方法也同步运行,这最终成为您已经显示的所有代码。
由于您需要此操作以异步方式运行,为了不阻止UI线程,您别无选择,只能使用Task.Run
来呼叫ReadTextAsync
(或ReadAsync
如果您愿意)确保操作实际异步运行。