0

The code looks like this:

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;
    }

The output looks like:

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
....

But my worker_progressChanged was never called until the end of the loop (int i = 0; i < 100; i++), and my progress bar was hence never updated and stays at 0. To my understanding, the ProgressChanged belongs to UI thread. What should I do to have my ProcessChanged fired immediately after ReportProgress is called?

Jimmothy
  • 11
  • 1
  • That is very much by design, ReportProgress does not bog down the worker thread. If you absolutely have to, don't, then you have to interlock it yourself. Use an AutoResetEvent. Wait() in the worker, Set() in the event handler. – Hans Passant Mar 15 '18 at 15:04
  • Thank you. How should I use AutoResetEvent? I tried to pause the eventhandler using autoresetevent.wait() and set() in the reportprogress, but it seems to pause everything besides do_worker now. – Jimmothy Mar 15 '18 at 15:32
  • Wait() in the worker code, after the ReportProgress() call. That prevents the worker from continuing. Set() in the ProgressChanged event handler, that signals the worker to keep going. – Hans Passant Mar 15 '18 at 15:46

1 Answers1

0

From msdn:

The call to the ReportProgress method is asynchronous and returns immediately

It doesn't block the for loop inside DoWork.

If you want to report progress synchronously, then you can use synchronous Invoke method yourself (see e.g. this). In such case you don't even need BackgroundWorker, just another Thread.

Sinatr
  • 20,892
  • 15
  • 90
  • 319