Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
后台工作人员c#立即停止工作人员(包括线程。在DoWork中睡眠)_C#_Backgroundworker - Fatal编程技术网

后台工作人员c#立即停止工作人员(包括线程。在DoWork中睡眠)

后台工作人员c#立即停止工作人员(包括线程。在DoWork中睡眠),c#,backgroundworker,C#,Backgroundworker,当我按下按钮时,我想停止我的后台工作人员: 代码看起来像: 按钮: private void button6_Click(object sender, EventArgs e) { backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; if (isOn ==

当我按下按钮时,我想停止我的后台工作人员: 代码看起来像:

按钮:

 private void button6_Click(object sender, EventArgs e)
        {

            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;

            if (isOn == true)
            {
                isOn = false;

                if (!backgroundWorker1.IsBusy)
                {


                    backgroundWorker1.RunWorkerAsync();
                    this.button6.ForeColor = System.Drawing.Color.Lime;
                }
            }
            else
            {
                isOn = true;
                this.button6.ForeColor = System.Drawing.Color.Red;
                backgroundWorker1.CancelAsync();
                //////backgroundWorker1.Dispose();

            }
我的后台工作人员看起来像:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {

        if (backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy)
        {
            e.Cancel = true;
            return;
        }
        while (true)
        {

            if (backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy)
            {
                e.Cancel = true;
                break;
            }

            backgroundWorker1.Dispose();
                click_na_default(hwnd1);
                click_F8(hwnd1);
                click_na_YELLS(hwnd1);
                click_ENTER(hwnd1);
                Thread.Sleep(100);
                click_na_trade(hwnd1);
                Thread.Sleep(100);
                click_F8(hwnd1);
                click_ENTER(hwnd1);
                Thread.Sleep(100);
                click_na_default(hwnd1);
                Thread.Sleep(4000);

        }

        if (((BackgroundWorker)sender).CancellationPending)
        {
            e.Cancel = true;
            //set this code at the end of file processing
            return;
        }



    }
问题是:我不能
.CancelAsync()再次按下按钮后立即执行。我的代码一直工作到线程。睡眠(4000)
;结束了。 当我按下我的按钮停止工作时,这将在循环结束后停止

我知道我可以补充

 if (backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy)
            {
                e.Cancel = true;
                return;
            }
在我的
Backgroundworker\u DoWork中的每一行之后
,但这太愚蠢了,当我得到
线程时。Sleep(10000)
;需要10秒。。。 有没有办法立即杀死我的背景工作人员?
谢谢你的帮助

我认为标准的
BackgroundWorker
不适合您的情况,您应该做一些定制的事情,更好地支持睡眠和取消的组合。以下代码是您可能希望执行的操作:

可取消的BackgroundWorker.cs

这是一个类似于标准
BackgroundWorker
的类,但为您的目标提供了一些回调(请参见
ICancellationProvider
FinishedEvent

public delegate void cancelablebackgroundjob(ICancellationProvider cancellation);
公共接口ICancellationProvider
{
bool CheckForCancel();
void CheckForCancelAndBreak();
取消无效休眠(整数毫秒);
}
公共类CancelableBackgroundWorker:组件,ICancellationProvider
{
私有只读ManualResetEvent _canceledEvent=新的ManualResetEvent(假);
私人只读可取消的backgroundJob\u backgroundJob;
私有易失性线程_线程;
私人易变资产处置;
公共事件处理程序FinishedEvent;
public cancelablebackgroundworker(cancelablebackgroundjob backgroundJob)
{
_背景工作=背景工作;
}
受保护的覆盖无效处置(布尔处置)
{
取消();
_这是真的;
}
私有无效资产NotDisposed()
{
如果(_)
抛出新的InvalidOperationException(“工人已被处置”);
}
公共图书馆很忙
{
获取{return(_thread!=null);}
}
公开作废开始()
{
AssertNotDisposed();
如果(_thread!=null)
抛出新的InvalidOperationException(“工作进程已启动”);
_线程=新线程(DoWorkWrapper);
_thread.Start();
}
公开作废取消()
{
AssertNotDisposed();
_canceledEvent.Set();
}
私有void DoWorkWrapper()
{
_canceledEvent.Reset();
尝试
{
_背景工作(本);
Debug.WriteLine(“工作线程成功完成”);
}
捕获(线程异常异常)
{
WriteLine(“工作线程被中止”);
Thread.ResetAbort();
}
最后
{
_canceledEvent.Reset();
_线程=null;
EventHandler finished=FinishedEvent;
如果(已完成!=null)
已完成(此,EventArgs.Empty);
}
}
#区域单元提供者
//使用接口的显式实现来分离接口
//我太懒了,无法创建其他类
bool ICancellationProvider.CheckForCancel()文件
{
返回_canceledEvent.WaitOne(0);
}
ICancellationProvider.CheckForCancelAndBreak()无效
{
如果(((ICancellationProvider)this.CheckForCancel())
{
WriteLine(“设置了取消事件,中止工作线程”);
_thread.Abort();
}
}
无效ICancellationProvider.SleepWithCancel(整数毫秒)
{
如果(_canceledEvent.WaitOne(毫秒))
{
WriteLine(“通过取消事件中止睡眠,中止工作线程”);
_thread.Abort();
}
}
#端区
}
主要技巧是使用
ManualResetEvent.WaitOne
而不是
Thread.Sleep
进行睡眠。使用这种方法,工作线程可以从不同的(UI)线程安全地唤醒(取消)。另一个技巧是通过
Thread.Abort
使用
ThreadAbortException
强制快速结束后台线程执行(不要忘记堆栈展开结束时的
Thread.ResetAbort

您可以按以下方式使用此类:

公共部分类表单1:表单
{
私有只读可取消backgroundWorker\u backgroundWorker;
公共表格1()
{
初始化组件();
_backgroundWorker=新的可取消backgroundWorker(DoBackgroundJob);
_backgroundWorker.FinishedEvent+=(s,e)=>UpdateButton();
//确保this.components由InitializeComponent或由我们显式创建
//所以我们可以添加_backgroundWorker到它中进行处理
if(this.components==null)
this.components=new System.ComponentModel.Container();
组件。添加(_backgroundWorker);
}
私有void UpdateButton()
{
//确保我们在主线程上与UI交互
如果(需要调用)
{
调用((操作)UpdateButton);
返回;
}
按钮1.Text=\u backgroundWorker.IsBusy?“取消”:“开始”;
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
如果(_backgroundWorker.IsBusy)
{
_backgroundWorker.Cancel();
}
其他的
{
_backgroundWorker.Start();
}
UpdateButton();
}
私有无效DoBackgroundJob(ICancellationProvider取消)
{
Debug.WriteLine(“做某事”);
//如果取消,请立即停止
取消。检查取消和中断();
Debug.WriteLine(“做更多的事情”);
if(cancellation.CheckForCancel())
{
//你