【发布时间】:2017-01-17 15:23:08
【问题描述】:
前景:我正在调查一个 ASP.NET Core 项目(针对 .NET 4.6.1,使用来自 .Net Standard 1.4 的程序集)中的一个错误,该错误引发了 MissingMethodException,尽管这绝不可能。隔离了错误方法,我将代码的核心带到了一个单独的单元测试中,该单元测试也以 .NET 4.6.1 为目标。
我从单元测试中收到的异常ThreadAbortException 或多或少是这样的(有时是不同的):
at System.Net.Http.WinHttpHandler.SetRequestHandleDecompressionOptions(SafeWinHttpHandle requestHandle)
at System.Net.Http.WinHttpHandler.SetRequestHandleOptions(WinHttpRequestState state)
at System.Net.Http.WinHttpHandler.<StartRequest>d__103.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Hub.Test.UnitTest1.<FetchUrlAsync>d__2.MoveNext()
上述异常的代码:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
//FetchUrl(); // works
var task = FetchUrlAsync(); // does not work
}
private void FetchUrl()
{
var handler = new HttpClientHandler();
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (var client = new HttpClient(handler, true))
{
var response = client.SendAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("https://github.com/dotnet/core"))).Result;
Trace.WriteLine("FetchUrl:" + response.StatusCode);
}
}
private async Task FetchUrlAsync()
{
try
{
var handler = new HttpClientHandler();
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (var client = new HttpClient(handler, true))
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, new Uri("https://github.com/dotnet/core")));
Trace.WriteLine("FetchUrlAsync: " + response.StatusCode);
}
}
catch (Exception e)
{
Trace.WriteLine(e);
throw;
}
}
}
请注意,如果我调用 FetchUrl() 代码可以工作。是的,我知道这在我调用 result 的那一刻就变成了一种同步方法,但这仅用于演示目的。
但是,错误方法 FetchUrlAsync() 不断抛出 ThreadAbortException。
使用 SendAsync 的原因是,原始实现是一个通用的实现,它使用这种方法完成所有 Http* 工作。 GetAsync 等也可以触发相同的错误。
我无法弄清楚我在这里做错了什么,但我怀疑这个错误是 .NET CLR 中的某个错误。
更新
虽然单元测试问题已解决(谢谢),但我在 ASP.NET Core web-api 中仍然遇到问题。据我了解,.NET Standard 1.4 和 .NET Framework 4.6.1 应该是 1-1 兼容的。这就是为什么我认为框架中存在一个罕见的错误,尽管这似乎不太可能。
共同点是 System.Net.Http;这与 .NET Standard 1.4 和 .NET Framework 4.6.1 不同;我倾向于找出问题所在,并将答案发布给可能遇到类似问题的其他人。
【问题讨论】:
-
好吧,首先你不是
awaiting 任务。 -
在一种方法中
response是Task<HttpResponseMessage>,另一种方法是HttpResponseMessage,但您似乎对它们都一视同仁。 -
@juharr 注意非异步方法末尾的
.Result。 -
你必须等待
FetchUrlAsync否则测试将在SendAsync有机会返回之前退出 -
Touché,Oleg .. 我一直在盯着这个。我很抱歉。这个“快速”结论的原因是,我发现 .NET Standard 1.4 和 .NET Framework 在通用 API 方面的一些特性。
标签: c# .net asynchronous async-await dotnet-httpclient