WinForms 执行同步方法,在不阻塞 UI 的情况下调用异步方法 [英] WinForms execute synchronous method that calls an async method without blocking UI

查看:29
本文介绍了WinForms 执行同步方法,在不阻塞 UI 的情况下调用异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图让驱动程序在 WinForms 应用程序中工作(我希望我可以使用 WPF,但这里不是一个选项),但我遇到了一个有趣的问题.当在驱动程序中调用 await 方法时,UI 线程将永远阻塞.这是我的问题的一个非常简化的版本,这似乎只发生在 Windows 窗体应用程序上.

So I'm trying to get a driver working in a WinForms application (I wish I could go WPF but that is not an option here) and I'm running into an interesting problem. The UI thread blocks forever when an await method is called in the driver. Here is a very simplified version of my problem, again this only seems to happen on Windows Forms applications.

private void button_Click(object sender, EventArgs e)
{
    MessageBox.Show(this.TestSynchronous().ToString());
}

// I'm trying to avoid having to change the code below
private int TestSynchronous()
{
    return this.TestAsync().Result;
}

private async Task<int> TestAsync()
{
    await Task.Delay(100);

    var rand = new Random();

    return rand.Next();
}

有什么方法可以包装对TestSynchronous"方法的调用以防止它永久阻塞 UI 线程?请记住,我试图避免以任何方式更改测试"方法.

Is there a way I can wrap the call to the 'TestSynchronous' method to prevent it from permanently blocking the UI thread? Remember I'm trying to avoid having to change the 'Test' methods in any way.

我看过类似的帖子,比如 await 工作但调用task.Result 挂起/死锁,这与我的问题类似,但我的问题无法以同样的方式解决.原因是他可以直接访问正在等待的异步方法,而我没有.所以重申一下,我正在调用一个只向我提供TestSynchronous"方法的库,我想知道是否有任何方法可以包装该方法,因此它不会最终阻塞到我所在的库的某处无权更改代码.

I've seen similar posts like duplicate like await works but calling task.Result hangs/deadlocks which are similar to my problem but my problem cannot be solved the same way. The reason being he has direct access to the async method being awaited whilst I do not. So to reiterate, I'm calling into a library that only presents me with the 'TestSynchronous' method and I want to know if there's any way I can wrap the method so it doesn't end up blocking somewhere down into the library where I don't have access to change the code.

推荐答案

所以我实际上能够解决这个问题,答案其实很简单.这是示例的修改版本.

So I was actually able to solve this problem and the answer was actually pretty simple. Here is the modified version of the example.

private void button_Click(object sender, EventArgs e)
{
    var task = Task.Run<int>(
            () => this.TestSynchronous());

    task.Wait();

    MessageBox.Show(task.Result.ToString());
}

还有其他方法可以有效地做同样的事情,但这似乎对我的问题有效.有趣的是,我之前(在发布我的问题之前)曾尝试使用类似的方法修复它,但它不起作用,但现在它起作用了,所以我不知道我做错了什么.

There are other methods to do effectively the same thing but this appears work for my problem. The funny thing is I had previously (before posting my question) attempted to fix it using a similar method and it didn't work but it does now so I don't know what I did wrong.

这篇关于WinForms 执行同步方法,在不阻塞 UI 的情况下调用异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆