所以,我正在创建一个下载管理器,我已经专门设计了每一个位,以便它可以在任何时候关闭而不给它时间清理。但是,我似乎无法找到杀死我的下载程序线程的方法。我尝试使用Thread.Abort(实际上,这是我给他们时间清理的方式:他们捕获ThreadAbortException并自己处理它),但正如你已经猜到的那样,这并不好。我会使用标志或其他东西,但是当一个线程正在等待网络操作完成时,它几乎完全被阻止了。关于如何至少中断网络操作的任何想法,以便我可以在不等待显着时间的情况下关闭?
以下是相关的代码:
try
{
Request.AddRange(StartPosition, EndPosition);
Owner.SetDefaultRequestParameters(Request);
Response = Request.GetResponse() as HttpWebResponse;
ResponseStream = Response.GetResponseStream();
var Buffer = new Byte[Downloader.BUFFER_SIZE];
while (true)
{
Paused.Wait();
if (bStopRequested)
break;
int Count = ResponseStream.Read(Buffer, 0, Buffer.Length); //gets stuck here
if (Count == 0)
break;
MemoryStream.Write(Buffer, 0, Count);
Downloaded += Count;
CurrentStreak += Count;
if (StartPosition + Downloaded >= EndPosition)
break;
if (MemoryStream.Capacity - CurrentStreak < Buffer.Length)
{
Owner.WriteToFile(MemoryStream, StartPosition + Downloaded - CurrentStreak, CurrentStreak);
MemoryStream.Seek(0, SeekOrigin.Begin);
CurrentStreak = 0;
}
}
}
catch (ThreadAbortException)
{
try
{
Response.Close();
}
catch { }
return; //fastest way I have found to shut the thread down, yet
}
编辑:所以,我就是这样做的:
if (Request != null)
Request.Abort();
if (Response != null)
Response.Close();
ExecutionThread.Abort();
有了这个,无论线程卡在哪里(从响应流中获得响应或读取),它都会被取消并立即停止。
答案 0 :(得分:2)
您可以处置ResponseStream
,然后抓住ObjectDisposedException
。
虽然这可行,但我建议您使用CancellationToken设计应用程序以允许它正常关闭而不是中断中止线程。您还可以考虑使用async-await
来使您的应用程序更具可扩展性和非阻塞性。
答案 1 :(得分:1)
不确定底层套接字的作用但是如果全部失败,您可以直接以非阻塞模式绑定到套接字,并使用Socket.BeginReceive方法,该方法将在数据到达时调用您的回调。如果你想取消当前的操作,你可以简单地调用关闭套接字就可以了。 见MSDN
必须通过调用完成异步BeginReceive操作 EndReceive方法。通常,该方法由 回调代表。
在操作完成之前,此方法不会阻止。阻止 直到操作完成,使用Receive方法之一 过载。
要取消待处理的BeginReceive,请调用关闭方法。
您应该检查是否可以将手放在底层插座上并尝试关闭它。