Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.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# 我应该将后台工作人员传递给方法吗_C#_Backgroundworker - Fatal编程技术网

C# 我应该将后台工作人员传递给方法吗

C# 我应该将后台工作人员传递给方法吗,c#,backgroundworker,C#,Backgroundworker,我有一个应用程序,有几个方法,需要很长时间才能完成。我正在使用backgroundworker来运行这些方法并保持UI的响应性。我的方法看起来像 public void DoSomething() { while( HaveMoreWork ) { // do work } } 现在我希望UI能够在任何时候取消此操作,因此我已更改了我的方法,以采用类似的Backgroundworker public void DoSomething(Backgroundworker

我有一个应用程序,有几个方法,需要很长时间才能完成。我正在使用backgroundworker来运行这些方法并保持UI的响应性。我的方法看起来像

public void DoSomething()
{
   while( HaveMoreWork )
   {
     // do work
   }
}
现在我希望UI能够在任何时候取消此操作,因此我已更改了我的方法,以采用类似的Backgroundworker

public void DoSomething(Backgroundworker worker)
{

   while( HaveMoreWork && !worker.CancelationPending )
   {
     // do work
   }
}

我的问题是,有没有更好的办法。似乎将一个幕后推手作为所有这些方法的论据是有点混乱的。这方面的最佳实践是什么

我正在使用全局变量

public class DoSomethingService
{
    private volatile bool _stopped = false;

    public void Start(object socketQueueObject)
    {
        while (!_stopped)
        {
            ...
        }
    }

    public void Stop()
    {
        _stopped = true;
    }
}

...

var doSomethingService = DoSomethingService();
doSomethingService.Start();
...
doSomethingService.Stop();
private BackgroundWorker _bwSearch = new BackgroundWorker();

private void InitializeBackgroundWorker()
{
     _bwSearch = new BackgroundWorker();
     _bwSearch.WorkerSupportsCancellation = true;
     _bwSearch.DoWork += bwSearch_DoWork;
     _bwSearch.RunWorkerCompleted += bwSearch_RunWorkerCompleted;
}
单击停止按钮时

 private void btnCancel_Click(object sender, EventArgs e)
 {
      _bwSearch.Abort();
 }

更新: 我还使用这个从BackgroundWorker继承的简单助手类

public class AbortableBackgroundWorker : BackgroundWorker
    {
        private Thread _workerThread;

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            _workerThread = Thread.CurrentThread;

            try
            {
                base.OnDoWork(e);
            }
            catch (ThreadAbortException)
            {
                e.Cancel = true;

                Thread.ResetAbort();
            }
        }

        public void Abort()
        {
            if (_workerThread != null)
            {
                _workerThread.Abort();

                _workerThread = null;
            }
        }
    }

他们必须知道worker(作为参数或全局变量)。这看起来不错。BackgroundWorker使用线程池,这意味着您永远不应该对BackgroundWorker调用abort。我相信更好的方法是将您的btnCancel\u单击更改为:if(\u bwSearch.IsBusy)\u bwSearch.CancelAsync();