【问题标题】:Calling BackgroundWorker synchronously同步调用BackgroundWorker
【发布时间】:2018-07-20 05:02:04
【问题描述】:

我想同步调用后台工作者。我希望在后台工作人员完成执行后结束代码的执行。 我的 BackgroundWorker 代码在这里:

{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += DoWork;
    worker.RunWorkerCompleted += RunWorkerCompleted;
    ...
    worker.RunWorkerAsync();
    //wait for execution to end 
}

这样做的一种方法是再次检查状态 n 直到其执行完成,但是还有其他好的方法吗?

【问题讨论】:

  • 如果同步等待,使用 BackgroundWorker 有什么意义?
  • 为什么不在 RunWorkerCompleted 事件下,在 BackgroundWorker 完成后移动你想要执行的代码部分?
  • @AhmedMasud:您应该专注于修复该错误,而不是构建解决方法。
  • @ChrisGessler 但是如果你同步等待后台工作人员结束,你无论如何都会阻塞 UI
  • @ChrisGessler“使用 Async 和 Await 进行异步编程”,同步如何? ;)

标签: c# backgroundworker


【解决方案1】:

如果你不希望你的代码异步执行,不要把它放在BackgroundWorker...

{ 
    DoWork();
} 

但是,如果有一些不明确的原因绝对需要在BackgroundWorker 中包含代码,则可以使用以下内容:

ManualResetEvent mre = new ManualResetEvent(false);
BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += DoWork; 
worker.RunWorkerCompleted += (s, e) => 
                             {
                                 RunWorkerCompleted(s, e); 
                                 mre.Set();
                             };
// ... 
worker.RunWorkerAsync();
mre.WaitOne();

【讨论】:

    【解决方案2】:

    目标:BackgroundWorker 应该同步执行。

    创建了一个 Windows 应用程序表单。单击 button1 时,它应该同步执行 BackgroundWorker 并返回参与 UI,因此用户在完成 BackgroundWorker 任务之前无法执行任何操作。

    public partial class Form1 : Form 
    { 
    
        public Form1() 
        { 
            InitializeComponent(); 
        }
    
        BGimplent obj = null;
    
        private void button1_Click(object sender, EventArgs e)
        {
            int i = 0;
             obj = new BGimplent();
            obj.eveBG += obj_eveBG;
            i = 5;
            obj.MyProperty = 5;
            obj.DoConfig();
            obj.ManualReset.WaitOne();
    
            obj.MyProperty = 10;
            obj.MyProperty = 11;
            obj.MyProperty = 12;
            obj.MyProperty = 13;
    
            obj.MyProperty = 14;
        }
    
        void obj_eveBG(string s)
        {
            obj.ManualReset.Set();
            MessageBox.Show(s);
        }
    }
    
    
    
    /*
    *******************************************************
        Paste below code in adding new class i.e. Class1
    
    
    */
    public delegate void delBG(string s);
    
    class BGimplent
    {
        public event  delBG eveBG;
    
    
        private ManualResetEvent mnuReset = new ManualResetEvent(false);
        public ManualResetEvent ManualReset { get; set; }
    
        public int MyProperty { get; set; }
    
        BackgroundWorker bgWorker = new BackgroundWorker();
        public void DoConfig()
        {
            ManualReset = mnuReset;
    
            bgWorker.DoWork += bgWorker_DoWork;
            bgWorker.ProgressChanged += bgWorker_ProgressChanged;
            bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
            bgWorker.RunWorkerAsync();            
        }
    
        void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {   
            Thread.Sleep(5000);
            if (eveBG != null)
                eveBG("Value of MyProperty: " + MyProperty.ToString());
        }
    
    }
    

    【讨论】:

    • @GhostCat 是的,你是对的。我尽力通过我的帖子回答这个问题。
    • @GhostCat 感谢您的建议,我编辑了代码并试图将其呈现得更具吸引力。
    • 我会进一步“缩短”空方法体 - 但现在好多了;-)
    【解决方案3】:

    //wait for execution to end 之后的代码应放在 worker_RunWorkerCompleted 方法中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 2016-03-24
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      相关资源
      最近更新 更多