2015-10-07 25 views
10

プロジェクトをWCFからWeb API(SelfHost)に移植しました。処理中にWebアプリケーションを提供する際に非常に減速していました。現在は40-50秒と3秒前です。ASP.NET Web API 2 - StreamContentが極端に遅い

私は、次のコントローラとAspNet.WebApiとOwinSelfHostのための様々なNuget pacakgesを追加することにより、簡単なコンソールアプリケーションで問題を再現しました:

var stream = new MemoryStream(); 
using (var file = File.OpenRead(filename)) 
{ 
    file.CopyTo(stream); 
} 
stream.Position = 0; 

var response = Request.CreateResponse(System.Net.HttpStatusCode.OK); 

/// THIS IS FAST 
response.Content = new ByteArrayContent(stream.ToArray()); 
/// THIS IS SLOW 
response.Content = new StreamContent(stream); 

response.Content.Headers.ContentType = new MediaTypeHeaderValue(System.Web.MimeMapping.GetMimeMapping(filename));    
response.Content.Headers.ContentLength = stream.Length; 

あなたが唯一の違いはあるコードから見ることができるようにStreamContent(slooooow)とByteArrayContentの使い方。

アプリケーションはWin10マシンでホストされ、私のラップトップからアクセスします。 Fiddlerは、StreamContentを使用してサーバーからラップトップに1MBのファイルを1つ取得するのに14秒かかり、ByteArrayContentは1秒未満であることを示しています。

また、唯一の違いは使用されるコンテンツクラスであることを示すために、完全なファイルがメモリに読み込まれることにも注意してください。

奇妙なことは、転送そのものが遅いようです。サーバーはすぐに/すぐにヘッダで応答しますが、データはフィドラータイミング情報によって示されるように到着するのに長い時間がかかる:

GotResponseHeaders: 07:50:52.800 
ServerDoneResponse: 07:51:08.471 

完全なタイミング情報:

== TIMING INFO ============ 
ClientConnected: 07:50:52.238 
ClientBeginRequest: 07:50:52.238 
GotRequestHeaders: 07:50:52.238 
ClientDoneRequest: 07:50:52.238 
Determine Gateway: 0ms 
DNS Lookup:   0ms 
TCP/IP Connect:  15ms 
HTTPS Handshake: 0ms 
ServerConnected: 07:50:52.253 
FiddlerBeginRequest:07:50:52.253 
ServerGotRequest: 07:50:52.253 
ServerBeginResponse:07:50:52.800 
GotResponseHeaders: 07:50:52.800 
ServerDoneResponse: 07:51:08.471 
ClientBeginResponse:07:51:08.471 
ClientDoneResponse: 07:51:08.471 

Overall Elapsed: 0:00:16.233 

、誰もが何が起こっているのか知っていますフードの下では、行動の違いを説明することができますか?

+0

こんにちは、まったく同じ問題に直面しています。あなたは解決策を見つけましたか? – DanielG

+1

@DanielG:恐れることはありませんが、https://connect.microsoft.com/VisualStudio/feedback/details/1932717/asp-net-bug-issueにバグレポートを掲載しました。もしあなたがそれに投票して、「私もできる」リンク(Reprosの隣)をクリックするといいですね。 – TommyN

+0

さて、それを行います。 1つの質問:データがすでにメモリに入っている場合、ByteArrayContentだけを使用してみてはどうでしょうか? – DanielG

答えて

14

OWIN自己ホスティングのための私の問題の解決策は、StreamContentバッファサイズでした。 StreamContentのデフォルトのコンストラクタでは、既定値0x1000、4KBが使用されます。ギガビットネットワークでは、26Mbファイルの転送には〜60Kb/sの速度で完了するのに7分かかります。

const int BufferSize = 1024 * 1024; 
responseMessage = new HttpResponseMessage(); 
responseMessage.Content = new StreamContent(fileStream, BufferSize); 

バッファサイズを1Mbに変更すると、ダウンロードが完了するまで数秒で完了します。

[編集] StreamContent SerializeToStreamAsyncでStreamToStreamCopyを実行すると、this linkのパフォーマンスが異なります。適切な値はおそらく80Kです。

0

プロジェクトを遵守したら、デバッグからリリースに変更してみてください。それはちょっとしたパフォーマンスでひどくパフォーマンスを増やすだろう。

+1

のように到着するまでに時間がかかります。違いはありません。 – TommyN

3

私は同じ問題に直面している。私はOwinセルフホスティングに関連していると思う。私はAsp.netサンプルアプリケーションを作成し、それをIIS上でホストしました。その場合、期待どおりに機能しました。

私Testsystemの結果80メガバイトのファイルをダウンロード中:StreamcontentとIISホスティングと< 30秒

  • :Streamcontentとセルフホスティングと

    • :ByteArrayContentとセルフホスティングで〜20分
    • を: < 30秒

    ASP.netでの設定がありますが、自分のホストしているプロject、またはowin self-hostingコードにバグがあります。

  • 関連する問題