Wpf Dispatcher Pause and Continue

1.6k Views Asked by At

I have a list view that is bound to a collection.

The collection is updated using the dispatcher.current dispatcher so that the items get added incrementally to the list view.

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
      if(continueDispatcher)numDone = DoStuff();
}));

This works really well, and the continueDispatcher flag stops the thread dead in its tracks, which is cool, but I would like to be able to continue the dispatcher operations on a button click.

I have read about dispatcher frames and the like but I dont seem to be able to find a solution that works.

Has anyone got any ideas on this issue?

Edit - More Code

//for each image
foreach (var result in results)
{
    result.Type = type;

    numDone = LoadImagesAsync(result, numDone, total);
}

private int LoadImagesAsync(Item result, int numDone, int total)
{
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
    {
        //keep looping
        while (true)
        {
            //if the dispatcher is paused then continue the loop
            if (DispatcherPaused) continue;

            //if the dispatcher is not paused then perform the action and break out of the loop
            numDone = DoStuff(result, numDone, total);
            break;
        }
    }));
    return numDone;
}

private int DoStuff(Item result, int numDone, int total)
{
    ItemList.Add(result);
    numDone++;
    ProgressBarValue = ((double) numDone/total)*100;
    return numDone;
}
  • C#
  • Visual Studio 2012
2

There are 2 best solutions below

1
On BEST ANSWER
Thread t = new Thread(() =>
{
    while (true)
    {
       if (continueDispatcher)
           numDone = DoStuff();
        Thread.Sleep(50);
    }
});
t.Start();
0
On

First, you should never block/monopolize the UI thread like this. Find some other way to manage a long-running, interruptable task. If possible, use a BackgroundWorker and do the bulk of the work on another thread, while marshaling back to the UI thread to report progress and commit your results (either a little at a time, or all at once).

Also, if you want to 'pause' an operation, you shouldn't just busy-wait in a loop. That will send your CPU usage through the roof. In general, you should use some sort of wait handle to send the thread into a waiting state until you notify it to resume (but never do this to the UI thread).