Update C # Chart Using BackgroundWorker

I am currently trying to update a diagram that is in my background worker form using:

bwCharter.RunWorkerAsync(chart1); 

What is done:

 private void bcCharter_DoWork(object sender, DoWorkEventArgs e) { System.Windows.Forms.DataVisualization.Charting.Chart chart = null; // Convert e.Argument to chart //.. // Converted.. chart.Series.Clear(); e.Result=chart; setChart(c.chart); } private void setChart(System.Windows.Forms.DataVisualization.Charting.Chart arg) { if (chart1.InvokeRequired) { chart1.Invoke(new MethodInvoker(delegate { setChart(arg); })); return; } chart1 = arg; } 

However, at the time of cleaning the series, an exception is thrown.

Basically, I want to do a lot more processing after cleaning the series, which completely slows down the GUI - I wanted it in another thread.

I thought that passing this as an argument, I should be safe, but apparently not!

Interestingly, the chart is on the tab. I can run it again and again if the tab is in the background, but if I run it, look at the chart, hide it again and run again, it throws an exception. Obviously, he throws if the chart is also in the foreground.

Can anyone suggest what I can do differently?

Thanks!


EDIT: I know this can be done as a stream, as when I return it again. However, the whole point of using a background worker is to avoid interrupting the entire program. As I said, processing is much more than this command.

I assumed that passing it as an argument would allow me to freely access it in this thread, but is there any chance that this graph traversed still indicates the original graph? If so, how can this be overcome?

I want to block the GUI thread as little as possible, so it makes no sense to just call each command.

+4
source share
4 answers

If you want to clear it first and then do a lot of asynchronous work before redrawing it, why don't you call chart.Series.Clear(); before you call BackgroundWorker ? In this case, it is cleared by the main user interface thread, after which you do the som async job before you install the diagram again from the user interface thread.

Also, when using BackgroundWorker I would use the ReportProgress and WorkerCompleted built-in events to avoid using manual cross-threading. This is part of the reason for using BackgroundWorker in the first place to get such functionality for “free.” Therefore, you must configure the chart in WorkerCompleted to simplify your code (even if this is not the source of the problem in this case).

+4
source

Check for Invoke Required in bcCharter_DoWork, if so, also put the Clear method call on the delegate.

  if (InvokeRequired) { Invoke(new MethodInvoker(delegate { chart.Series.Clear(); e.Result=chart; })); return; } 
+1
source

I agree with the analysis in previous posts: you request a thread to access the resource of another thread.
As you used BackgroundWorker, I suggest you use a dispatcher:

 private void bcCharter_DoWork(object sender, DoWorkEventArgs e) { Chart chart = null; Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { chart.Series.Clear(); })); } 
+1
source

The problem you are facing is that you cannot access user interface elements in streams other than those on which they were created. However, in your case, you can simply clear the chart before calling the background worker.

You can manually march access to the user interface element to the correct stream from another stream using Control.Invoke .

0
source

Source: https://habr.com/ru/post/1335378/


All Articles