【问题标题】:How to thread/which thread to use for background DLing .NET如何线程/哪个线程用于后台 DLing .NET
【发布时间】:2009-10-30 12:16:20
【问题描述】:
我正在编写连接到数据库并下载指定项目所需的任何包的前端应用程序。用户应该能够关闭不再启动任何 DL 并等待当前完成的应用程序以及强制关闭选项,该选项将断开当前下载并退出。
我正在下载的文件可能在几个不是我自己的服务器上。我应该使用什么样的线程? IIRC 在.NET 上有不止一种类型。如果用户请求立即关闭,我可以使用哪些命令告诉他们现在关闭(这可能与终止不同)?
【问题讨论】:
标签:
c#
.net
winforms
networking
multithreading
【解决方案1】:
在给定的场景中,您应该能够使用诸如 HttpWebRequest / WebClient 之类的异步特性,它们已经支持所有这些,使用完成端口而不仅仅是线程。
重新“立即终止” - 除非您正在拆除您的进程,否则您永远不应该中止线程。这是一个坏事,并且可能使系统处于损坏状态或无法恢复的锁。然而,工具本身可能会提供替代方案:
WebClient wc = new WebClient();
wc.DownloadFileCompleted += (sender, args) =>
{
if (args.Cancelled) Console.WriteLine("cancelled");
else if (args.Error != null) Console.WriteLine(args.Error.Message);
else Console.WriteLine("got it");
};
wc.DownloadFileAsync(uri, filePath);
// wc.CancelAsync(); // to abort
请注意,在异步回调(上面的 DownloadFileCompleted)中,您必须在 winforms/wpf 之类的任何东西中切换到 UI 线程;例如:
wc.DownloadFileCompleted += (sender, args) =>
{
this.Invoke((MethodInvoker) delegate {
if (args.Cancelled) txtStatus.Text = "cancelled";
else if (args.Error != null) txtStatus.Text = args.Error.Message;
else txtStatus.Text = "got it";
});
};
【解决方案2】:
线程只有一种,但有多种使用方式。由于您使用的是 GUI(WinForms?),因此 BackgroundWorker 是最合适的。
您可以从那里使用异步或同步 I/O。
你不应该 Abort() 一个线程,而是关闭或取消你的连接。取决于你想用什么。
【解决方案3】:
您可能应该查看 ThreadPool.QueueUserWorkItem