简体   繁体   English

在不等待的情况下调用异步方法 #2

[英]call async method without await #2

I have an async method:我有一个异步方法:

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);
    }
}

I call this method like this:我这样称呼这个方法:

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

Can i call the same method from an synchronous method, without using await keyword?我可以在不使用await关键字的情况下从同步方法调用相同的方法吗?

Ex:前任:

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

I think this will cause a deadlock.我认为这会导致僵局。

EDIT编辑

Calling the method like above makes the call never end.调用上面的方法使调用永不结束。 (The method doesn't reaches the end anymore) (该方法不再结束)

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.如果从单线程执行上下文(例如 UI 线程)调用异步方法,并同步等待结果,则死锁的可能性很高。 In your example, that probability is 100%在您的示例中,该概率为 100%

Think about it.想想看。 What happens when you call当你打电话时会发生什么

ValidateRequestAsync(userName, password).Result

You call the method ValidateRequestAsync.您调用方法 ValidateRequestAsync。 In there you call ReadAsStringAsync.在那里你调用 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.结果是一个任务将被返回到 UI 线程,当它变得可用时,一个延续被安排在 UI 线程上继续执行。 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.但是任务无法完成,因为它正在等待 UI 线程变为可用。 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;

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. UI 线程上的原始调用者可能是某个事件处理程序,因此请确保它是异步的。

你可以使用return ValidateRequestAsync(userName, password).GetAwaiter().GetResult();

For me it worked using .ConfigureAwait(false) setting in the async call.对我来说,它在异步调用中使用 .ConfigureAwait(false) 设置工作。 I have something like我有类似的东西

return await Entities.SingleOrDefaultAsync(.....).ConfigureAwait(false);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM