除了停止按钮外,我还有以下功能可以正常工作。它正在停止线程池但是当我再次点击开始时它显示后台工作者仍然忙。暂停也有效。
如何正确停止后台工作人员和所有线程池?
public bool stop = false;
private object signal = new object();
private static EventWaitHandle PauseEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
private void start_button_Click(object sender, EventArgs e)
{
if (this._BackgroundWorker.IsBusy)
{
MessageBox.Show("busy", "test", MessageBoxButtons.OK);
return;
}
/////////////////////////////////////////////////////////////////////////
//some code
/////////////////////////////////////////////////////////////////////////
starting();
}
private void stop_button_Click(object sender, EventArgs e)
{
if (start == true)
{
stop = true;
//this._BackgroundWorker.CancelAsync();
progressBar1.Value = 0;
/////////////////////////////////////////////////////////////////////////
//some code
/////////////////////////////////////////////////////////////////////////
}
}
private void starting()
{
ThreadPool.SetMinThreads(5, 5);
ThreadPool.SetMaxThreads(10, 10);
/////////////////////////////////////////////////////////////////////////
//some code
/////////////////////////////////////////////////////////////////////////
this._BackgroundWorker.WorkerReportsProgress = true;
this._BackgroundWorker.WorkerSupportsCancellation = true;
this._BackgroundWorker.RunWorkerAsync();
}
private void _BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (this._BackgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
/////////////////////////////////////////////////////////////////////////
//some code
/////////////////////////////////////////////////////////////////////////
for (int i = 0; i < cnt; i++)
{
string argument = this.listView1.CheckedItems[i].Text;
this.DoSend(argument);
}
}
private void DoSend(object sender)
{
int activeWorkers = 0;
StreamReader reader = new StreamReader(E_LIST);
do
{
lock (reader)
{
line = reader.ReadLine();
}
/////////////////////////////////////////////////////////////////////////
//some code
/////////////////////////////////////////////////////////////////////////
lock (signal)
{
++activeWorkers; // keep track of active workers
}
ThreadPool.QueueUserWorkItem(
o =>
{
myfunction(argument);
lock (signal) // signal termination
{
--activeWorkers;
Monitor.Pulse(signal);
}
}, state);
lock (signal)
{
while (activeWorkers > 0 || stop == true)
{
Monitor.Wait(signal);
this._BackgroundWorker.CancelAsync();
}
}
this.add();
crt++;
}
//start progressbar
int iProgressPercentage = (int)(((double)crt / (double)total) * 100);
if (iProgressPercentage <= 100)
_BackgroundWorker.ReportProgress(iProgressPercentage);
//end progresbar
PauseEvent.WaitOne();
}
while (reader.Peek() != -1);
reader.Close();
}
谢谢!
答案 0 :(得分:0)
我会考虑解雇雇佣的程序员。没有必要这样做这两种方式。这很麻烦。
对于这个问题 -
您需要在for循环中添加取消检查。
for (int i = 0; i < cnt; i++)
{
if (this._BackgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
string argument = this.listView1.CheckedItems[i].Text;
this.DoSend(argument);
}