2017-01-17 11 views
1

Foreground:.NET Coreプロジェクト(.Net Standard 1.4のアセンブリを使用して.NET 4.6.1をターゲットにする)のバグを調査していましたが、MissingMethodExceptionがスローされましたが、これは決して可能ではありませんでした。障害のあるメソッドを分離するために、コードのコアを.NET 4.6.1をターゲットとする別の単体テストに取り出しました。.NET Core(.NET Standard 1.4および.NET Framework 4.6.1)でSystem.Net.Httpにawait/asyncを使用している場合のバグはありますか?

ユニットテストは、多かれ少なかれ、この(それいつか様々な)であるから、私は、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() 

abolve例外の問題のコード:

[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()を呼び出すと、コードが機能することになります。はい、私は結果が呼び出された瞬間にこれが同期メソッドになったことを知っていますが、デモンストレーションの目的のみです。

しかし、FetchUrlAsync()メソッドは、ThreadAbortExceptionをスローし続けます。

SendAsyncの理由は、元の実装が、この1つのメソッドをすべてのHttp *作業に使用する一般的な実装であるということです。同じエラーがGetAsyncなどでトリガされる可能性があります。

ここで間違っていることはわかりませんが、このエラーは.NET CLRのどこかのバグであると思われます。

UPDATE

ユニットテストの問題は、ASP.NETコアの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からビット単位で変化します。私は問題が何であるかを知り、同様の問題を抱えている可能性のある他の人に答えを投稿する傾向があります。

+1

まず、あなたはタスクを待っていません。 – DavidG

+0

'response'は' Task 'であり、もう一つは' HttpResponseMessage'ですが、どちらも同じように扱われているようです。 – juharr

+0

@juharr非同期メソッドの最後に '.Result'があることに注意してください。 – DavidG

答えて

2

さて、によって報告MissingMethodExceptionたオリジナルの問題を解決するために:それはない場合、あなたはWait()を使用する必要があります

[TestMethod] 
public async Task TestMethod1() 
{ 
    await FetchUrlAsync();  
} 

:この場合、あなたの試験方法は、に変更しますコントローラの1つ。

このエラーは、非同期/待機の組み合わせを使用した場合にのみトリガされました。これは、シーンの背後にあるコンパイラで生成されたコードのために意味があります。

はNugetアセンブリの一つが.NET Standard Library 1.6.1からSystem.Net.Httpを使用し、このアセンブリパッケージは(紙の上に、.NET Framework 4.6.1と互換性が1-1である).NET標準1.4標的こと、が判明しました。

私を溶液混じり、そしてこれまでのところは良いFileNotFoundException: Could not load file or assembly 'System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

を生成することができました。

bin/debugフォルダを調べるときに問題が明らかになりました。組み込みのFrameworkアセンブリを使用していたため、System.Net.Http.dllが見つかりませんでした。

Aha。

"frameworkAssemblies": [ 
     "System.Net.Http" 
    ] 

は、このリファレンスはMicrosoft.AspNetCore.Authentication/1.1.0Microsoft.IdentityModel.Protocols/2.1.0から来た:溶液を通して見るVISUAL STUDIO 2015

は、ビルトインFrameworkアセンブリへの参照のみがproject.lock.jsonにありました。

この2つのframeworkAssembliesエントリを削除すると、「実際の」System.Net.Http.dllがbin/debugフォルダにコピーされたため、ソリューションが機能しました。

VISUAL STUDIO 2017

ほぼ同じ問題。 Microsoftはproject.jsonの使用は推奨されていないので、しかし、ここでの解決策は、次の内容のapp.configファイルを変更(または追加)することです:

<configuration> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
</configuration> 

私はこの長い記事のために申し訳ありません人をしています。バグがあり、フレームワークにないかもしれません。証拠がmsbuildや異なるIDEを指しているかもしれません。私はエラーを見つけて訂正することができたことをうれしく思います。

これはかなり長いエントリが同様の問題を持つ他の人に役立つことを望みます。

ハッピーコーディング!

+0

関連性があります:https://github.com/dotnet/ corefx/issues/9846 –

+0

.NET標準の詳細:https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/ –

1

テストメソッドは非同期メソッドが終了するのを待たないので、テストはSendAsyncが返す前に終了します。

使用するテストフレームワークは指定していませんが、非同期テストをサポートしていると仮定しています。

[TestMethod] 
public void TestMethod1() 
{ 
    FetchUrlAsync().Wait();  
} 
関連する問題