Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 重复使用BackgroundWorker,取消并等待它_C#_Multithreading_Backgroundworker - Fatal编程技术网

C# 重复使用BackgroundWorker,取消并等待它

C# 重复使用BackgroundWorker,取消并等待它,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,假设您有一个搜索文本框,并将搜索算法附加到TextChanged事件,该事件与BackgroundWorker一起运行。如果文本框中出现新字符,我需要取消上一次搜索并再次运行 我尝试在主线程和bgw之间使用事件,但仍然出现错误“当前正忙,无法同时运行多个任务” 不要重复使用后台工作人员。它是一种廉价的资源,而不是线程 确保您的Bgw代码停止,您的代码看起来正常。Bgw将把线程释放到池中 但同时,为新作业创建新任务/Bgw 您可能希望从旧Bgw取消订阅已完成的活动 如果旧后台工作程序存在,请创建

假设您有一个搜索文本框,并将搜索算法附加到TextChanged事件,该事件与BackgroundWorker一起运行。如果文本框中出现新字符,我需要取消上一次搜索并再次运行

我尝试在主线程和bgw之间使用事件,但仍然出现错误“当前正忙,无法同时运行多个任务”

  • 不要重复使用后台工作人员。它是一种廉价的资源,而不是线程
  • 确保您的Bgw代码停止,您的代码看起来正常。Bgw将把线程释放到池中
  • 但同时,为新作业创建新任务/Bgw
  • 您可能希望从旧Bgw取消订阅已完成的活动
如果旧后台工作程序存在,请创建新的后台工作程序

private void SearchWithBgw()
{
    // cancel previous search
    if (bgw_Search.IsBusy)
    {
        bgw_Search.CancelAsync();

        // wait for the bgw to finish, so it can be reused.
        _resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
        BackgroundWorker bgw_Search = new BackgroundWorker();
        bgw_Search.DoWork += new DoWorkEventHandler(bgw_Search_DoWork);


    }

    // start new search
    bgw_Search.RunWorkerAsync();   // error "cannot run multiple tasks concurrently"
}

另外,我知道您输入了伪代码,但您希望确保在代码正常完成时设置了
\u resetEvent

当_resetEvent.WaitOne()调用完成时,工作线程实际上没有完成。它正忙于从DoWork()返回并等待运行RunWorkerCompleted事件(如果有)的机会。这需要时间


没有可靠的方法确保以同步方式完成BGW。在IsBusy上阻塞或等待RunWorkerCompleted事件运行将导致死锁。如果您真的只想使用一个bgw,那么您必须对请求进行排队。或者干脆别为小事操心,再分配一个bgw。他们花费很少。

< P>我认为你应该考虑不取消背景工作者。

如果您取消请求,并且用户键入的速度快于服务器返回的查询速度,则在完成键入之前,他不会看到建议

在这样的交互场景中,最好显示与用户键入内容相关的响应。如果用户想到的单词是你的建议列表,他就会知道他可以停止输入

当服务器繁忙时,这对您的服务器也会更好,因为与许多取消的请求不同,这些请求将花费一些费用,但最终不会显示,而您实际使用的响应将更少


我在(3d)渲染应用程序中遇到了类似的问题,初学者的错误是取消并重新渲染每个鼠标移动。这会导致大量的计算和很少的交互反馈

如果我在此函数中创建了一个
新的BackgroundWorker()
,我如何取消上一个?我应该把工人列在名单上还是什么的?由于搜索功能更新控件,我不希望多个工作人员更新同一个控件。@Carlos,在创建新控件之前,请取消旧控件并等待它单独出现_resetEvent。+1谢谢,说得好。我觉得有必要取消,因为我在后台工作中更新了GUI,我不想让多个工作人员更新同一个控件。
    private void SearchWithBgw()
    {   
        if (bgw_Search.IsBusy)
        {
            bgw_Search.CancelAsync();
            _resetEvent.WaitOne(); // will block until _resetEvent.Set() call made

            bgw_Search = new BackgroundWorker();
            bgw_Search.WorkerSupportsCancellation = true;
            bgw_Search.DoWork += new DoWorkEventHandler(bgw_Search_DoWork);
        }

        bgw_Search.RunWorkerAsync();        
    }
private void SearchWithBgw()
{
    // cancel previous search
    if (bgw_Search.IsBusy)
    {
        bgw_Search.CancelAsync();

        // wait for the bgw to finish, so it can be reused.
        _resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
        BackgroundWorker bgw_Search = new BackgroundWorker();
        bgw_Search.DoWork += new DoWorkEventHandler(bgw_Search_DoWork);


    }

    // start new search
    bgw_Search.RunWorkerAsync();   // error "cannot run multiple tasks concurrently"
}