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);
すべての非同期呼び出しがスレッドプールに依存していることは知っていましたが、スレッドを強制終了する方法はありますか?
非同期操作を強制終了するためのコントロールをいくつか配置しました
外部タイマーを配置しました。トリガーでストリームを閉じます
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"); }
ストリームを閉じていますが、何らかの理由でアプリケーションがまだハングしています。
外部タイマーを配置し、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);
}