【问题标题】:C# WPF / WinForms - Calling async method in WPF / WinForm never finishesC# WPF / WinForms - 在 WPF / WinForm 中调用异步方法永远不会完成
【发布时间】:2018-10-11 09:08:13
【问题描述】:

当我尝试在我的 WPF 项目中调用异步方法时,它永远不会停止并返回任何内容。

我尝试了几种方法,例如:

1:

public wndMain()
{
    InitializeComponent();
    Initialize();
}

private void Initialize()
{
    IList<Docker.DotNet.Models.ContainerListResponse> myContainers = myClient.Containers.ListContainersAsync(new Docker.DotNet.Models.ContainersListParameters() { All = true }).Result;
}

2:

public wndMain()
{
    InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    IList<Docker.DotNet.Models.ContainerListResponse> myContainers = myClient.Containers.ListContainersAsync(new Docker.DotNet.Models.ContainersListParameters() { All = true }).Result;
}

但是什么都没有发生,当我调试它在这个方法调用处停止并且什么都没有发生。

讽刺的是:

当我在 C# 控制台应用程序中调用完全相同的方法时,它正在运行……不知道为什么。

第二个讽刺的是:

当我创建一个 C# Windows 窗体应用程序并将代码放在 Program.cs 中的“Application.Run(frmMain)”后面时,它也在运行。


那么我的异步方法调用和 WPF/Forms 有什么问题?

【问题讨论】:

  • 它是否曾经通过该方法并允许您的 WPF 应用程序执行其余的操作?听起来像一个僵局。
  • 它在这个过程步骤停止,当我查看内存时没有任何变化。当这是死锁的定义 - 那么它就是死锁! :)
  • 等待.Result为什么还是异步的?
  • @Kevin 对提供的答案有何反馈?
  • 我必须解决死锁。目前我没有源代码,但我知道我使用了“任务”类,事件“Window_Loaded”不是异步的,但是通过这种方式,异步方法不会陷入死锁。像这样:字符串代码 = Task.Run(GenerateCodeAsync).Result;

标签: c# wpf winforms asynchronous


【解决方案1】:

当我调试它时,它会在这个方法调用处停止,什么也没有发生。

.Result 阻塞调用导致死锁。

事件处理程序允许async void。因此,您的第二个选项可以重构为等待结果而不阻塞 UI 线程

private async void Window_Loaded(object sender, RoutedEventArgs e) {
    IList<Docker.DotNet.Models.ContainerListResponse> myContainers = 
        await myClient.Containers.ListContainersAsync(new Docker.DotNet.Models.ContainersListParameters() { All = true });
}

参考Async/Await - Best Practices in Asynchronous Programming

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多