I have the doubt regarding when to use the Dispatcher.Invoke to update something on UI from different Thread.
Here’s my code…
public Window4()
{
InitializeComponent();
this.DataContext = this;
Task.Factory.StartNew(() => Test() );
}
private List<string> listOfString = new List<string>();
public List<string> ListOfString
{
get { return listOfString; }
set { listOfString = value; }
}
public void Test()
{
listOfString.Add("abc");
listOfString.Add("abc");
listOfString.Add("abc");
}
<Grid>
<ListView ItemsSource="{Binding ListOfString}" />
</Grid>
I am starting a new Task on the different Thread, do i need to use Dispatcher.BeginInvoke to update the UI.
In this case it is updating the UI, but i’ve seen some scenarios where people update UI using Dispatcher.Invoke or BeginInvoke from the different Thread.
So my question is when we have to do that and why in this case it is working fine.
Thanks & Regards,
BHavik
When you are on a different thread you will always have to use the dispatcher to update a ui component that belongs to another thread.
Tasks allow for multiple operations to be performed without blocking the thread they are called from but that doesn’t mean they are on a different thread. However when updating the UI from inside a Task you will need to use the dispatcher.
Invoke will block the calling thread while it is performing the action and BeginInvoke will not. BeginInvoke will return control immediately to the caller, Invoke may cause the calling thread to hang if it is performing a heavy operation.
This is from msdn documentation,
Edit: In response to your comment I ran some tests.
When calling Test() from a task (without using the dispatcher) I got this error “The calling thread cannot access this object because a different thread owns it.”
So I created a method called PrintThreadID(). I printed the thread before entering the task then from inside the task and it does report both are running on the same thread ID.
The error is misleading because it says the calling thread is different than the one that owns it which the PrintThreadID() function shows is not true, they are in fact on the same thread. Tasks while on the same thread still cannot update a UI component without using Dispather.Invoke().
So here is a working example which will update the Grid from a task.