我有以下四个测试,运行时最后一个挂起,我的问题是为什么会这样:
[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; } }
为什么最后一个测试挂起?
您正遇到我在博客和MSDN文章中描述的标准死锁情况:该async方法正尝试将其继续安排在被调用阻塞的线程上Result。
async
Result
在这种情况下,您SynchronizationContext是NUnit执行async void测试方法的人。我会尝试使用async Task测试方法来代替。
SynchronizationContext
async void
async Task