c# - 如何处理使 UI 无响应的同步(阻塞)调用

标签 c# .net async-await system.reactive

鉴于这段代码,我注意到我的 UI 有一段时间被阻塞了(Windows 甚至弹出一条消息说应用程序没有响应。

using (var zip = await downloader.DownloadAsZipArchive(downloadUrl))
{
    var temp = FileUtils.GetTempDirectoryName();
    zip.ExtractToDirectory(temp);   // BLOCKING CALL

    if (Directory.Exists(folderPath))
    {
        Directory.Delete(folderPath, true);
    }

    var firstChild = Path.Combine(temp, folderName);
    Directory.Move(firstChild, folderPath);
    Directory.Delete(temp);
}

经过一些检查,我发现那一行说:

zip.ExtractToDirectory(temp);

是罪魁祸首。

我认为把它变成就足以让它工作了:

await Task.Run(() => zip.ExtractToDirectory(temp));

但是……这是解决这个问题的好方法吗?

我有 System.Reactive 的背景(我完全参与响应式编程),我想知道是否有更优雅的方法来处理这个问题。

最佳答案

在 Rx 中这样做有点讨厌。结合 Task<IDisposable>很粗糙。这是我得到的:

Observable
    .FromAsync(() => downloader.DownloadAsZipArchive(downloadUrl))
    .SelectMany(z =>
        Observable
            .Using(() => z, zip => Observable.Start(() =>
            {
                var temp = FileUtils.GetTempDirectoryName();
                zip.ExtractToDirectory(temp);   // BLOCKING CALL

                if (Directory.Exists(folderPath))
                {
                    Directory.Delete(folderPath, true);
                }

                var firstChild = Path.Combine(temp, folderName);
                Directory.Move(firstChild, folderPath);
                Directory.Delete(temp);             
            })))
    .Subscribe();

关于c# - 如何处理使 UI 无响应的同步(阻塞)调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54564325/

相关文章:

c# - 使用异步方法的结果

c# - 示例代码中是否需要 Task.WhenAll?

c# - MVC5 Ninject 绑定(bind)和 HttpContext

c# - .NET - Excel ListObject 在数据绑定(bind)时自动调整大小

c# - 具有两个来源的 WPF 图像

c# - 误报 : precondition is redundant

.net - Microsoft 完整版 .NET Framework 4.8 是否有任何结束日期

c# - 等待和不分配任务

c# - 在样式中找不到可附加属性触发器

C# 应用程序到 C++ dll 通过回调返回到 C# 应用程序