2017-08-14 11 views
1

SQL Serverに格納されているコンテンツをvarbinary(max)としてクライアントにストリーミングしようとしています。私はそれを動作させることができますが、接続はガベージコレクションまで開いたままになります。結果を返す前にコネクション、リーダまたはスチームを廃棄すると、オブジェクトにエラーが発生します。ASP.NET MVCでSQL Serverストリームファイルを出力して接続を切断する

データがメモリにコピーされるのを避けるため(大規模な可能性があります)、処理が完了した時点でオブジェクトを適切に破棄します。これらの目標を達成するための最良の方法は何でしょうか。

私は.NET Core 2.0を使用していますが、これが適切です。

更新:これは、ストリームを破棄する方法を尋ねるのではなく、関連する接続オブジェクトを破棄する方法を尋ねているので、他のものと重複していません(How do I dispose my filestream when implementing a file download in ASP.NET?)。

public async Task<IActionResult> DownloadFile(Guid FileId) 
{ 
    var connection = new SqlConnection(DatabaseService.ConnectionString); 

    await connection.OpenAsync(); 
    var command = connection.CreateCommand(); 

    command.CommandText = "select FileName, FileContent from Files where [email protected]"; 
    command.CommandType = System.Data.CommandType.Text; 
    command.Parameters.AddWithValue("@FileId", FileId); 

    var reader = await command.ExecuteReaderAsync(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.SingleRow); 

    if (!await reader.ReadAsync()) 
     return NotFound(); 
    var attachmentName = Convert.ToString(reader[0]); 

    var stream = reader.GetStream(1); 

    var response = File(stream, "application/octet-stream", attachmentName); 
    return response; 
} 

オブジェクトを破棄し、以下のこのコードはそれだけには失敗します。私の質問は、接続オブジェクトが

が配置されていることを確認し、以下のコードが正常に結果を返しますが、非配置された接続を離れるの適切な方法についての詳細ですそれは

public async Task<IActionResult> DownloadFile(Guid FileId) 
{ 
    using (var connection = new SqlConnection(DatabaseService.ConnectionString)) 
    { 

     await connection.OpenAsync(); 
     using (var command = connection.CreateCommand()) 
     { 

      command.CommandText = "select FileName, FileContent from Files where [email protected]"; 
      command.CommandType = System.Data.CommandType.Text; 
      command.Parameters.AddWithValue("@FileId", FileId); 

      using (var reader = await command.ExecuteReaderAsync(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.SingleRow)) 
      { 

       if (!await reader.ReadAsync()) 
        return NotFound(); 
       var attachmentName = Convert.ToString(reader[0]); 

       using (var stream = reader.GetStream(1)) 
       { 

        var response = File(stream, "application/octet-stream", attachmentName); 
        return response; 
       } 
      } 
     } 
    } 
} 
+0

を持っている場合、私は、ストリームを処分する方法を求めておりませんので、これは他人から重複していない明確にするため、この答えを追加、更新されたコード

public async Task<IActionResult> DownloadFile(Guid FileId) { var connection = new SqlConnection(DatabaseService.ConnectionString); HttpContext.Response.RegisterForDispose(connection); await connection.OpenAsync(); var command = connection.CreateCommand(); HttpContext.Response.RegisterForDispose(command); command.CommandText = "select FileName, FileContent from Files where [email protected]"; command.CommandType = System.Data.CommandType.Text; command.Parameters.AddWithValue("@FileId", FileId); var reader = await command.ExecuteReaderAsync(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.SingleRow); HttpContext.Response.RegisterForDispose(reader); if (!await reader.ReadAsync()) return NotFound(); var attachmentName = Convert.ToString(reader[0]); var stream = reader.GetStream(1); HttpContext.Response.RegisterForDispose(stream); var response = File(stream, "application/octet-stream", attachmentName); return response; } 

ですが、むしろ関連する接続オブジェクトをどのように処分するかということです。私の質問は、接続オブジェクトが確実に廃棄されるようにする適切な方法です。 – webwake

+0

@musefan残念ながらあなたの新しい例(https://stackoverflow.com/questions/37956254/asp-net-core-mvc-get-file-from-database)イメージのレンダリング)はストリーミングの必要性に対処せず、受け入れられた答えは応答を送信する前にコンテンツ全体をメモリストリームにロードします。 – webwake

+0

信頼できるオプションがありません。接続は限られているため、できるだけ早く処分する必要があります。すべてのデータを読み込んで接続を終了し、データを送信するのがはるかに良い方法です。登録やオブジェクトの処分など、他の方法もありますが、接続を開いたままにしておけば、それには利点はありません。 –

答えて

2

デイビット・ブラウンの答えは私に情報を与えました。私はHttpContext.Response.RegisterForDispose();を使って使い捨てコンポーネントを登録する必要がありました。これにより、要求が完了した後に廃棄されます。以下は

私は他の人が同じ問題

+0

あなた自身の答えを受け入れるべきです。はるかに良い、他の人は少しの努力をしており、おそらくちょうどコメントされている必要があります – musefan

関連する問題