0

I have a wpf control, a chart, in which the user can interact with the mouse.

Now I have a time heavy calculation every time the mouse moves, it needs around 700 ms to do (even after a bunch of performance reviews). The result should be displayed within a label.

So what I want to do is, when the mouse moves instead of doing right away and update the label (then the UI lags for nearly a second), I want to do this asynch and update the label when the calc is finished.

How to do that?

mdisibio
  • 3,148
  • 31
  • 47
PassionateDeveloper
  • 14,558
  • 34
  • 107
  • 176
  • Spawn a [BackgroundWorker](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?view=net-5.0) to do your calculation. It has an [OnRunWorkerCompleted](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker.onrunworkercompleted?view=net-5.0) method that runs when the work is done. You can dispatch changes to your UI there. – D M May 24 '21 at 13:52
  • Here are a couple of questions about using the `BackgroundWorker` class. [How to use a BackgroundWorker?](https://stackoverflow.com/questions/6481304/how-to-use-a-backgroundworker) [How to use the BackgroundWorker event RunWorkerCompleted](https://stackoverflow.com/questions/19723742/how-to-use-the-backgroundworker-event-runworkercompleted) – D M May 24 '21 at 13:54
  • 2
    I wouldn't use a Background Worker for this. `BackgroundWorker` is an old strategy used in the WinForms days; it will work, but WPF is designed to work with asynchronous methods, and you don't need to stand up a new thread to make this work properly. – Robert Harvey May 24 '21 at 14:17

1 Answers1

2

The simplest way would be to have an asynchronous event handler for the control, perform the CPU-heavy work on another thread using something like Task.Run(), and update the label when done. Something like this would work:

private async void Control_Event(object sender, EventArgs e)
{
    var result = await Task.Run(() => MyExpensiveCalculation());
    label.Text = result;
}

private string MyExpensiveCalculation()
{
    //Do your expensive calculation here and return the result.
}

Note that Task.Run() should be called from the UI thread. It should not be a part of the calculation implementation.

Patrick Tucci
  • 1,824
  • 1
  • 16
  • 22