【问题标题】:C# BackgroundWorker.ProgressChanged not fired immediately after ReportProgress is calledC# BackgroundWorker.ProgressChanged 在调用 ReportProgress 后没有立即触发
【发布时间】:2018-08-24 10:42:42
【问题描述】:

代码如下所示:

class Mainwindow: Window{ 

int progress = 0;

public void sendrequest(){

    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.ProgressChanged += new ProgressChangedEventHandler (             
    worker_ProgressChanged);
    worker.WorkerReportsProgress = true;
    worker.RunWorkerAsync();

    //...Here I sent requests to Bloomberg API 
    // Each request is handled by EventHandler

    session.SendRequest(request, null);
}


public void EventHandler(Event eventObject, Session session){
    progress ++;
    Console.WriteLine (process);
}

void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine("Doing work! calling progress report!");
            (sender as BackgroundWorker).ReportProgress(progress, null);
            Thread.Sleep(100);
        }

    }

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine("Started Change! " + e.ProgressPercentage);
        pg1.Value = e.ProgressPercentage;
    }

输出如下:

Doing work! calling progress report!
0
1
Doing work! calling progress report!
2
3
4
5
Doing work! calling progress report!
6
7
8
9
10
Doing work! calling progress report!
11
12
13
14
Doing work! calling progress report!
15
16
17
18
19
Doing work! calling progress report!
20
....

但是直到循环结束(int i = 0; i

【问题讨论】:

  • 这在很大程度上是设计使然,ReportProgress 不会使工作线程陷入困境。如果你绝对必须,不要,那么你必须自己联锁。使用 AutoResetEvent。工作者中的 Wait(),事件处理程序中的 Set()。
  • 谢谢。我应该如何使用 AutoResetEvent?我尝试在 reportprogress 中使用 autoresetevent.wait() 和 set() 暂停事件处理程序,但现在似乎暂停除了 do_worker 之外的所有内容。
  • Wait() 在工作代码中,在 ReportProgress() 调用之后。这会阻止工人继续工作。 ProgressChanged 事件处理程序中的 Set(),它向工作人员发出继续前进的信号。

标签: c# user-interface backgroundworker


【解决方案1】:

来自msdn

ReportProgress 方法的调用是异步的,立即返回

它不会阻塞DoWork 内的for 循环。

如果您想同步报告进度,那么您可以自己使用同步Invoke 方法(参见例如this)。在这种情况下,您甚至不需要BackgroundWorker,只需另一个Thread

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多