在不等待的情况下调用异步方法 #2 [英] call async method without await #2

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

问题描述

我有一个异步方法:

public async Task<bool> ValidateRequestAsync(string userName, string password)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);
        string stringResponse = await response.Content.ReadAsStringAsync();

        return bool.Parse(stringResponse);
    }
}

我这样调用这个方法:

bool isValid = await ValidateRequestAsync("user1", "pass1");

我可以从同步方法调用相同的方法,而不使用 await 关键字吗?

Can i call the same method from an synchronous method, without using await keyword?

例如:

public bool ValidateRequest(string userName, string password)
{
    return ValidateRequestAsync(userName, password).Result;
}

我认为这会导致僵局.

编辑

调用上述方法使调用永无止境.(方法没有结束)

Calling the method like above makes the call never end. (The method doesn't reaches the end anymore)

推荐答案

如果从单线程执行上下文(比如 UI 线程)调用异步方法,并同步等待结果,死锁的概率很高.在您的示例中,该概率为 100%

If you call an async method from a single threaded execution context, such as a UI thread, and wait for the result synchronously, there is a high probability for deadlock. In your example, that probability is 100%

想一想.当你打电话时会发生什么

Think about it. What happens when you call

ValidateRequestAsync(userName, password).Result

您调用方法 ValidateRequestAsync.在那里你调用 ReadAsStringAsync.结果是一个任务将被返回到 UI 线程,当它变得可用时,一个延续被安排在 UI 线程上继续执行.但当然,它永远不会变得可用,因为它正在等待(阻塞)任务完成.但是任务无法完成,因为它正在等待 UI 线程变为可用.死锁.

You call the method ValidateRequestAsync. In there you call ReadAsStringAsync. The result is that a task will be returned to the UI thread, with a continuation scheduled to continue executing on the UI thread when it becomes available. But of course, it will never become available, because it is waiting (blocked) for the task to finish. But the task can't finish, because it is waiting for the UI thread to become available. Deadlock.

有一些方法可以防止这种僵局,但它们都是一个坏主意.为了完整起见,以下可能有效:

There are ways to prevent this deadlock, but they are all a Bad Idea. Just for completeness sake, the following might work:

Task.Run(async () => await ValidateRequestAsync(userName, password)).Result;

这是个坏主意,因为您仍然会阻塞 UI 线程等待而没有做任何有用的事情.

This is a bad idea, because you still block your UI thread waiting and doing nothing useful.

那么解决方案是什么?一路异步.UI 线程上的原始调用者可能是某个事件处理程序,因此请确保它是异步的.

So what is the solution then? Go async all the way. The original caller on the UI thread is probably some event handler, so make sure that is async.

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

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