Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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# 取消使用lambda设置的Backgroundworker_C#_Lambda_Backgroundworker - Fatal编程技术网

C# 取消使用lambda设置的Backgroundworker

C# 取消使用lambda设置的Backgroundworker,c#,lambda,backgroundworker,C#,Lambda,Backgroundworker,我有一个使用lambda创建的backgroundworker,如下所示: BackgroundWorker fileCountWorker= new BackgroundWorker(); fileCountWorker.WorkerSupportsCancellation = true; fileCountWorker.DoWork += new DoWorkEventHandler((obj, e) => GetFileInfo(folder, subs)); fileCountWo

我有一个使用lambda创建的backgroundworker,如下所示:

BackgroundWorker fileCountWorker= new BackgroundWorker();
fileCountWorker.WorkerSupportsCancellation = true;
fileCountWorker.DoWork += new DoWorkEventHandler((obj, e) => GetFileInfo(folder, subs));
fileCountWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) => UpdateCountInFolderListViewForItem(index));
fileCountWorker.RunWorkerAsync(); 
我希望能够取消backgroundworker,然后使用RunWorkerCompletedEventArgs e.Cancelled属性在RunWorkerCompleted函数中知道它已被取消

到目前为止,我还无法找到一种方法将参数传递给RunWorkerCompleted函数,并且仍然能够访问RunWorkerCompletedEventArgs

我尝试向RunWorkerCompletedEventArgs调用的函数添加RunWorkerCompletedEventArgs参数,然后像这样传递RunWorkerCompletedEventArgs:

fileCountWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) => UpdateCountInFolderListViewForItem(index, e));
但这似乎不起作用

有办法做到这一点吗

编辑:

根据以下评论,我做了以下更改:

我更改了DoWork事件,如下所示,在worker函数中添加obj和e作为参数:

fileCountWorker.DoWork += new DoWorkEventHandler((obj, e) => GetFileInfo(folder, subs,obj,e));
fileCountWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) => UpdateCountInFolderListViewForItem(index, obj, e));
然后,我更改了RunWorkerCompleted函数,如下所示,在RunWorkerCompleted函数中添加obj和e作为参数:

fileCountWorker.DoWork += new DoWorkEventHandler((obj, e) => GetFileInfo(folder, subs,obj,e));
fileCountWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) => UpdateCountInFolderListViewForItem(index, obj, e));
从我的UI线程调用CancelAsync:

if (bgw.WorkerSupportsCancellation)
   {
      bgw.CancelAsync();
   }
然后从backgroundworker内部检查cancellationpending,如:

BackgroundWorker bwAsync = sender as BackgroundWorker;
if (bwAsync.CancellationPending)
   {
      e.Cancel = true;
      return;
   }
结果是,当我取消backgroundworker时,它确实停止了worker函数,但RunWorkerCompleted函数UpdateCountFolderListViewForItem中的UnworkerCompletedEventArgs仍将Cancelled属性设置为False,因此该函数无法判断该worker已被取消

因此,我仍然坚持让RunWorkerCompleted函数知道工作进程已被取消,而不是正常完成。

您只需要调用BackgroundWorker.CancelAsync

您的工作代码需要检查BackgroundWorker.CancellationPending并停止正在执行的操作以取消。。。但是,你的lambda没有做任何你可以真正取消的事情

通常情况下,您会这样做:

//...
fileCountWorker.DoWork += (obj, e) =>
{
    for (int i = 0; i < 1000 && fileCountWorker.CancellationPending; ++i)
    {
        Thread.Sleep(500);/* really do other work here */
    }
    e.Cancel = fileCountWorker.CancellationPending;
};

fileCountWorker.RunWorkerAsync(); 

//...

fileCountWorker.CancelAsync();

如果您提供GetFileInfo的一些详细信息,也许可以提供更多的详细信息。

将backgroundworker与lambdas一起使用是一个非常糟糕的主意。使用任务TPL或async/await或至少BeginInvoke。@Andrey想详细说明为什么lambda是一个非常糟糕的主意吗?@PeterRitchie,因为lambda是一个小的工作单元,并且有更多合适的工具来运行这些东西。@Andrey一个语句lambda可以有很多行,只要你想,假设您的.cs文件的长度不超过编译器所能接受的长度。lambda只是一种匿名方法…@Andrey谢谢Andrey,我不知道TaskTPL,但根据你的提示,我在codeproject上找到了一篇解释它的文章,我现在正在研究这一点。这就是为什么BackgroundWorker+lamdas不能很好地发挥作用的原因。@Andrey,以什么方式?@PeterRitchie问题是当我调用fileCountWorker.CancelAnsync;它确实会取消工作进程,然后调用RunWorkerCompleted函数,但是,我无法在RunWorkerCompleted函数中判断backgroundworker是自己完成的,还是被取消了,我将使用RunWorkerCompletedEventArgs测试哪个。GetFileInfo只是一个函数,它将DirectoryInfo用于枚举文件。因此,如果RunWorkerCompleted函数也是使用lambda创建的,您仍然可以从worker获取RunWorkerCompletedEventArgs吗?@Blau RunWorkerCompleted将始终被调用,即使您取消,请参见RunWorkerCompletedEventArgs.Cancelled。但要取消,代码需要检查CancellationPending。CancelAsync不会神奇地阻止代码运行,您的代码必须显式取消。RE event args:当然,lamba中的e是RunWorkerCompletedEventArgsobject@PeterRitchie根据你的建议,我做了一些修改,并将其作为编辑发布在原始帖子中。我还没弄明白。