1

HttpResponse.GetResponseStream() を非同期に読み込もうとしています

 Stream source=myHttpResponse.GetResponseStream();
 IAsyncResult asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);

しかし、何らかの理由でアプリケーションが source.Endread() でハングします

int bytesRead = source.EndRead(innerAsyncResult);

すべての非同期呼び出しがスレッドプールに依存していることは知っていましたが、スレッドを強制終了する方法はありますか?

非同期操作を強制終了するためのコントロールをいくつか配置しました

  1. 外部タイマーを配置しました。トリガーでストリームを閉じます

    System.Threading.Timer timer = new System.Threading.Timer(OnTimerCallback, source, Convert.ToInt32(new TimeSpan(0, 10, 0).TotalMilliseconds), 1); 
    
    private static void OnTimerCallback(Object state)
    {
        Stream stream = state as Stream;
    
        if (stream == null)
            return;
    
        try
        {
            stream.Close();
            stream.Dispose();
    
        }
        catch (Exception ex)
        {
            //Log Error
        }
    
        throw new Exception("Successfully closed the Stream and killing the Thread");
    }
    

    ストリームを閉じていますが、何らかの理由でアプリケーションがまだハングしています。

  2. 外部タイマーを配置し、asyncResult.AsyncWaitHandle.Close() を閉じました

どちらのメカニズムも無駄に思えます。スレッドを強制終了する方法はありますか。

基本的に私が達成したいのは、NetworkStream から読み取って FileStream に保存することです。しばらくは正常に動作し、後で source.EndRead(innerAsyncResult); でハングしました。Networkstream からの読み取りは非同期ですが、ファイルストリームへのデータの保存は同期です。

実際のコード:

public static void CopyToStreamAsync(this Stream source, Stream destination,
    Action<Stream, Stream, Exception> completed, Action<uint> progress,
    uint bufferSize)
{
    byte[] buffer = new byte[bufferSize];

    Action<Exception> done = exception =>
        { //Completed event handler
         };

    int maxDownloadSize = maximumDownloadSize.HasValue
        ? (int)maximumDownloadSize.Value
        : int.MaxValue;

    int bytesDownloaded = 0;
    IAsyncResult asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);

    Action<IAsyncResult, bool> endRead = null;
    endRead = (innerAsyncResult, innerIsTimedOut) =>
        {
            try
            {
                int bytesRead = source.EndRead(innerAsyncResult);

                int bytesToWrite = new[] { maxDownloadSize - bytesDownloaded, buffer.Length, bytesRead }.Min();

                destination.Write(buffer, 0, bytesToWrite);
                bytesDownloaded += bytesToWrite;

                if (!progress.IsNull() && bytesToWrite > 0)
                {
                   //Progress Handlers 
                }

                if (bytesToWrite == bytesRead && bytesToWrite > 0)
                {
                    asyncResult = source.BeginRead(buffer, 0, new[] { maxDownloadSize, buffer.Length }.Min(), null, null);                       
                    asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
                }
                else
                {
                    done(null);
                }
            }
            catch (Exception exc)
            {
                done(exc);
            }
        };

    asyncResult.FromAsync((ia, isTimeout) => endRead(ia, isTimeout), timeout);
}
4

0 に答える 0