gpt4 book ai didi

c# - 通过异步方法调用时,WinRT Metro 应用程序仍然阻塞 UI 线程

转载 作者:行者123 更新时间:2023-11-30 14:15:30 27 4
gpt4 key购买 nike

我有一个简单的 Metro 应用程序,其中包含一个按钮、一个标签和一个下拉列表。下拉列表包含我可以读取的文件列表。当我点击按钮时,所选文件的内容被读入标签。文件位于文档文件夹中(即 WinRT 的 KnownFolders.DocumentsLibrary)。每个文件代表 WinRT API 中的一个 StorageFile。

文件读取方法是一种异步方法(使用async/await)。为了证明异步行为,我将文件读取方法作为一个长时间运行的过程。因此,在执行这个长时间运行的方法时,我应该能够自由单击下拉列表并选择不同的文件。这是因为 UI 线程在读取文件时不应被阻塞。然而,这目前没有发生。它似乎仍然阻塞了 UI 线程,并且在长时间运行的方法发生时下拉列表被卡住。我一定是在这里做了一些奇怪的事情。您能告诉我为什么 UI 没有响应吗?我的代码示例如下。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace FileAccess
{
public sealed partial class MainPage : Page
{
private readonly StorageFolder storageFolder;

public MainPage()
{
this.InitializeComponent();
storageFolder = KnownFolders.DocumentsLibrary;
AddFiles();
}

private async void AddFiles() //Add files to the drop down list
{
var filesList = await storageFolder.GetFilesAsync();
IEnumerable<FileItem> fileItems
= filesList.Select(x => new FileItem(x.Name, x.Name));

cboSelectFile.ItemsSource = fileItems;
cboSelectFile.SelectedIndex = 0;
}


private async void BtnReadFile_Click(object sender, RoutedEventArgs e)
{
IStorageFile storageFile = await storageFolder.GetFileAsync((string)cboSelectFile.SelectedValue);

if (storageFile != null)
{
LblReadFile.Text = await ReadFileAsync(storageFile); //long running method**************
}
}


private async Task<string> ReadFileAsync(IStorageFile storageFile) //long running method**************
{
var fileContent = await FileIO.ReadTextAsync(storageFile);

for (Int64 i = 0; i < 10000000000; i++)
{
}

return fileContent;
}
}

最佳答案

如果您在 UI 线程上执行这样的代码:

var whatever = await DoSomethingAsync();
// some more code

然后 //一些代码 也将在 UI 线程上执行。这正是你的问题。读取文件后,您在 UI 线程上执行长循环,这就是 UI 卡住的原因。

如果你想模拟一些长时间运行的操作,你可以通过几种方式来实现:

  1. 使用 Task.Run() 在后台线程上执行循环,并异步等待它完成:

    private async Task<string> ReadFileAsync(IStorageFile storageFile)
    {
    var fileContent = await FileIO.ReadTextAsync(storageFile);

    await Task.Run(() => { for (Int64 i = 0; i < 10000000000; i++) {} });

    return fileContent;
    }
  2. 不要浪费 CPU 时间并使用 Task.Delay()延迟执行代码:

    private async Task<string> ReadFileAsync(IStorageFile storageFile)
    {
    var fileContent = await FileIO.ReadTextAsync(storageFile)
    .ConfigureAwait(false);

    await Task.Delay(TimeSpan.FromSeconds(10));

    return fileContent;
    }

关于c# - 通过异步方法调用时,WinRT Metro 应用程序仍然阻塞 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10001781/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com