最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】C#中BackgroundWorker中的DoWork执行了多次

C# crifan 8527浏览 0评论

【问题】

C#中,调试一个BackgroundWorker,发现一个问题:

DoWork在第一次执行完毕后,接下来,又进入了DoWork,

即DoWork被调用了多次。

 

【解决过程】

1.后来参考:

DoWork of BackgroundWorker is called twice when RunWorkerAsync is called once?

所以去看了看自己的代码,也是+=:

    private void getUrlRespStreamBytes_bw(ref Byte[] respBytesBuf,
                                string url,
                                Dictionary<string, string> headerDict,
                                Dictionary<string, string> postDict,
                                int timeout,
                                Action<int> funcUpdateProgress)
    {
        // Create a background thread
        gBgwDownload.DoWork += new DoWorkEventHandler(bgwDownload_DoWork);
        gBgwDownload.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgwDownload_RunWorkerCompleted);
        gBgwDownload.WorkerReportsProgress = true;
        gBgwDownload.ProgressChanged += new ProgressChangedEventHandler(bgwDownload_ProgressChanged);

        //init
        bNotCompleted_download = true;
        gFuncUpdateProgress = funcUpdateProgress;
        
        // run in another thread
        object paraObj = new object[] {respBytesBuf, url, headerDict, postDict, timeout};
        gBgwDownload.RunWorkerAsync(paraObj);
    }

所以就去把加号去掉:

    private void getUrlRespStreamBytes_bw(ref Byte[] respBytesBuf,
                                string url,
                                Dictionary<string, string> headerDict,
                                Dictionary<string, string> postDict,
                                int timeout,
                                Action<int> funcUpdateProgress)
    {
        // Create a background thread
        gBgwDownload.DoWork = new DoWorkEventHandler(bgwDownload_DoWork);
        gBgwDownload.RunWorkerCompleted = new RunWorkerCompletedEventHandler(bgwDownload_RunWorkerCompleted);
        gBgwDownload.WorkerReportsProgress = true;
        gBgwDownload.ProgressChanged = new ProgressChangedEventHandler(bgwDownload_ProgressChanged);

        //init
        bNotCompleted_download = true;
        gFuncUpdateProgress = funcUpdateProgress;
        
        // run in another thread
        object paraObj = new object[] {respBytesBuf, url, headerDict, postDict, timeout};
        gBgwDownload.RunWorkerAsync(paraObj);
    }

试试结果。

结果却是,直接语法错误,都无法运行。

2.同样参考上贴,去改为,去掉new handler的形式:

    private void getUrlRespStreamBytes_bw(ref Byte[] respBytesBuf,
                                string url,
                                Dictionary<string, string> headerDict,
                                Dictionary<string, string> postDict,
                                int timeout,
                                Action<int> funcUpdateProgress)
    {
        // Create a background thread
        gBgwDownload.DoWork += bgwDownload_DoWork;
        gBgwDownload.RunWorkerCompleted += bgwDownload_RunWorkerCompleted;
        gBgwDownload.WorkerReportsProgress = true;
        gBgwDownload.ProgressChanged += bgwDownload_ProgressChanged;

        //init
        bNotCompleted_download = true;
        gFuncUpdateProgress = funcUpdateProgress;
        
        // run in another thread
        object paraObj = new object[] {respBytesBuf, url, headerDict, postDict, timeout};
        gBgwDownload.RunWorkerAsync(paraObj);
    }

试试结果,结果问题依旧。

第二次调用DoWork后,紧接着,还是直接进入DoWork,而不是重新执行别的函数。

3.再去自己改为新建一个变量,而不是始终使用那个全局变量:

    private void getUrlRespStreamBytes_bw(ref Byte[] respBytesBuf,
                                string url,
                                Dictionary<string, string> headerDict,
                                Dictionary<string, string> postDict,
                                int timeout,
                                Action<int> funcUpdateProgress)
    {
        // Create a background thread
        gBgwDownload = new BackgroundWorker();
        gBgwDownload.DoWork += bgwDownload_DoWork;
        gBgwDownload.RunWorkerCompleted += bgwDownload_RunWorkerCompleted;
        gBgwDownload.WorkerReportsProgress = true;
        gBgwDownload.ProgressChanged += bgwDownload_ProgressChanged;

        //init
        bNotCompleted_download = true;
        gFuncUpdateProgress = funcUpdateProgress;
        
        // run in another thread
        object paraObj = new object[] {respBytesBuf, url, headerDict, postDict, timeout};
        gBgwDownload.RunWorkerAsync(paraObj);
    }

试试,结果就可以了。

 

【总结】

BackgroundWorker的DoWork被执行多次,原因是

之前BackgroundWorker初始化的时候,DoWork赋值时,都是

new DoWorkEventHandler

的形式,所以每次都新加了个DoWork动作,所以会导致后续多次调用时,被执行多次。

另外,不能每次都

gBgwValue += xx_doWork;

否则,也还是会多把后续的多次的DoWork都加到同一个全局变量gBgwValue上,导致后续DoWork被多次调用执行;

最终,改为,不带new DoWorkEventHandler的,每次是新建一个BackgroundWorker的变量,就可以了:

private BackgroundWorker gBgwDownload;
    
private void yourFunction_bw(xxx)
{
    // Create a background thread
    gBgwDownload = new BackgroundWorker(); /* added this line will fix problem */
    gBgwDownload.DoWork += bgwDownload_DoWork;
    gBgwDownload.RunWorkerCompleted += bgwDownload_RunWorkerCompleted;
    //omited some code
    gBgwDownload.RunWorkerAsync(paraObj);
}

转载请注明:在路上 » 【已解决】C#中BackgroundWorker中的DoWork执行了多次

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.165 seconds, using 22.09MB memory