MoonKnight
MoonKnight

Reputation: 23831

Wait for IProgress Report Method to Return

I am updating my UI via IProgress and the Report method. I do something like

IProgress<ProgressInfo> p = new Progress<ProgressInfo>(ReportProgress);
Task task = Task.Factory.StartNew(() =>
{
    result = Execute(p);
});

where in the Execute method I report progress via

p.Report(someObject);

Now, the issue is, in the last case where I report progress to the UI, I write something to a console window, which I use when the task has returned. The problem is that because IProgress is async, the task returns when the last progress report has not finished, leaving me without data.

I clearly could put the thread to sleep or spinwait, but this seems nasty to me as, although the report process will take a very short amount of time, I don't know the actual value to sleep etc. I have looked at using AutoResetEvent but again I am not sure this is the cleanest solution.

My question is how can I force the thread to wait for the return of the p.Report(someObject) call in the "cleanest" way possible, that is without relying on guessing at the time the report progress will take to return?

Upvotes: 4

Views: 1309

Answers (1)

Frank
Frank

Reputation: 4481

The Progress<T> class uses a SynchronizationContext to invoke the reporting handler in an asynchronous manner. This is done to update the UI on the UI thread in WPF or WinForms. If that's not what you want (and it obviously isn't needed in your Console application), don't use the IProgress<T> interface at all, or implement it yourself in a synchronous way:

  1. Go to ReferenceSource and duplicate the code into your project.

  2. Replace

    m_synchronizationContext.Post(m_invokeHandlers, value);
    

    with

    m_synchronizationContext.Send(m_invokeHandlers, value);
    

Upvotes: 4

Related Questions