Search code examples
c#wpfdispatcher

How do I send parameters of a delegate method from one thread to another with Dispacther.Invoke


I have made a WPF application. A sample of this application contains a usercontrol class which interacts with a second class (myClass2.cs). Inside myClass2.cs I have created a Canvas as a global variable on the main thread. I then create a new thread running as a STA. Once this thread has finished processing its data I want to plot the data on the Canvas stored on the main thread. In order to do this I have created a delegate which sends a polyline back to the main thread for plotting. I start with the following:

public delegate void canvasDel (Polyline polyline);
canvasDel handler = updateUI;  

public void updateUI(Polyline polyline)
{
    canvas.Children.Add(polyline);
}

I then use the application dispatcher and Invoke.

Application.Current.Dispatcher.Invoke(new Action(() =>  handler(polyline)));

The thread is now running on the main UI thread, but the polyline is still owned by the other thread and cannot be accessed. How do I pass the polyline to the main thread to update the Canvas?


Solution

  • You have to create the Polyline in the same thread where the Canvas was created, because all elements in a visual tree must be created in the same thread.

    Pass only the polyline points from the background thread to the UI thread:

    var points = new PointCollection(...); // in background thread
    
    canvas.Dispatcher.Invoke(() => canvas.Children.Add(
        new Polyline
        {
            Points = points,
            Stroke = Brushes.Black,
            StrokeThickness = 2
        }));