c# - 'await' 有效,但调用 task.Result 挂起/死锁

标签 c# nunit task deadlock async-await

我有以下四个测试,最后一个在我运行时挂起。为什么会这样:

[Test]
public void CheckOnceResultTest()
{
    Assert.IsTrue(CheckStatus().Result);
}

[Test]
public async void CheckOnceAwaitTest()
{
    Assert.IsTrue(await CheckStatus());
}

[Test]
public async void CheckStatusTwiceAwaitTest()
{
    Assert.IsTrue(await CheckStatus());
    Assert.IsTrue(await CheckStatus());
}

[Test]
public async void CheckStatusTwiceResultTest()
{
    Assert.IsTrue(CheckStatus().Result); // This hangs
    Assert.IsTrue(await CheckStatus());
}

private async Task<bool> CheckStatus()
{
    var restClient = new RestClient(@"https://api.test.nordnet.se/next/1");
    Task<IRestResponse<DummyServiceStatus>> restResponse = restClient.ExecuteTaskAsync<DummyServiceStatus>(new RestRequest(Method.GET));
    IRestResponse<DummyServiceStatus> response = await restResponse;
    return response.Data.SystemRunning;
}

我将此扩展方法用于 restsharp RestClient :

public static class RestClientExt
{
    public static Task<IRestResponse<T>> ExecuteTaskAsync<T>(this RestClient client, IRestRequest request) where T : new()
    {
        var tcs = new TaskCompletionSource<IRestResponse<T>>();
        RestRequestAsyncHandle asyncHandle = client.ExecuteAsync<T>(request, tcs.SetResult);
        return tcs.Task;
    }
}
public class DummyServiceStatus
{
    public string Message { get; set; }
    public bool ValidVersion { get; set; }
    public bool SystemRunning { get; set; }
    public bool SkipPhrase { get; set; }
    public long Timestamp { get; set; }
}

为什么最后一个测试挂了?

最佳答案

通过异步方法获取值:

var result = Task.Run(() => asyncGetValue()).Result;

同步调用异步方法

Task.Run( () => asyncMethod()).Wait();

不会因为使用Task.Run而出现死锁问题。

关于c# - 'await' 有效,但调用 task.Result 挂起/死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17248680/

相关文章:

c# - 在 C# 中将原始图像转换为位图

c# - 如何判断是为 selectmethod 还是 selectcountmethod 调用了 ObjectDataSource OnSelected 事件?

c# - nunit resharper 预期异常测试

c# - 在 Xunit 中处理多个测试用例的首选方法是什么?

c# - Task.Delay 超过 int.MaxValue 毫秒

github - 通过提交更新 github Markdown 任务列表 ( GFM )

c# - 跨线程控制

c# - 如何在c#代码中访问c++ dll类

c# - Task.Delay 与 Thread.Sleep 的区别

mono - 使用 Jenkins 在 Mono 中运行 NUnit