我正在尝试异步读取 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);
}