【发布时间】:2018-08-03 23:09:54
【问题描述】:
为了快速加载几个大文件,我启动了后台工作程序作为文件数量。
每个后台工作者需要很长时间来分别加载其文件。当他们加载文件时,我想停止所有加载。我了解 backgroundworker.CancelAsync() 向线程发送取消消息,但线程没有时间接受消息。因为每个线程只加载一个文件,并且没有循环操作来检查取消。在这种情况下,我该如何阻止这些后台工作人员?
让我在这里展示我的代码。 //主线程调用50个子线程。
private List<BackgroundWorker> bgws = new List<BackgroundWorker>();
private bool ChildThreadCompleted;
private void MainThread_DoWork(object sender, DoWorkEventArgs e)
{
// 50 sub threads will be started here
for (int i=1; i<=50; i++)
{
if (mainThread.CancellationPending) return;
BackgroundWorker childThread = new BackgroundWorker();
childThread.WorkerSupportsCancellation = true;
childThread.DoWork += ChildThread_DoWork;
childThread.RunWorkerCompleted += ChildThread_RunWorkerCompleted;
bgws.Add(childThread);
childThread.RunWorkerAsync(i);
}
while (!ChildThreadCompleted)
{
if (mainThread.CancellationPending)
{
foreach (BackgroundWorker thread in bgws)
if (thread.IsBusy) thread.CancelAsync();
}
Application.DoEvents();
}
}
private void ChildThread_DoWork(object sender, DoWorkEventArgs e)
{
int arg = Convert.ToInt32(e.Argument);
System.Threading.Thread.Sleep(1000);
BackgroundWorker thread = (BackgroundWorker)sender;
if (thread.CancellationPending) return;
// In case of loading the image no longer makes sense, I'd like to stop.
// At this point, i can't stop this process.
//loading large file here. Just one image file for example. <= this takes one or more seconds
e.Result = arg;
}
private void ChildThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BackgroundWorker thread = sender as BackgroundWorker;
bgws.Remove(thread);
if (bgws.Count == 0) ChildThreadCompleted = true;
}
【问题讨论】:
-
最好展示你的代码,因为我强烈怀疑你是关于任务,而不是线程本身。
-
请发布代码向我们展示问题;你的散文再清楚不过了。
-
您应该启用
WorkerSupportsCancellation并致电CancelAsync()。你的工人代表应该检查CancellationPending并回复它。 -
CancelAsync不会中止线程。它引发了CancellationPending标志。中止线程是一个非常糟糕的主意,因为它不允许代码优雅地终止、关闭连接等。 -
没有“取消消息”,它只是将一个 bool 变量设置为 true。工作线程必须在其主循环内检查它以了解何时中断。如果它是一个需要很长时间加载的单个文件,那么很长一段时间内都不会发生任何事情,因为工作人员也无法检查变量。如果你不能让文件加载代码更智能,你就无能为力了。
标签: c# .net backgroundworker