Is there a way to solve this error " The calling thread cannot access this object because a different thread owns it" without using dispatcher because dispatcher causes freezing on UI when the codes has a longer time to process is there another way to do it? without causing the freeze on the UI
-
2Let the "longer time process" run on a background/worker thread - not on the UI thread. Only if the result of this has been finally computed, invoke the UI through the dispatcher to assign the result to the appropriate UI element(s). – Jun 30 '14 at 04:13
-
Thank you the advice will try to apply in on my solution – bRaNdOn Jun 30 '14 at 04:19
-
Can you provide my some sample code for this kind of approach?? – bRaNdOn Jun 30 '14 at 04:34
-
What approach? From your question i deduce that you already know how to use the Dispatcher, or am i mistaken? – Jun 30 '14 at 04:35
-
1What version of .NET are you using? If you are using 4.0+, I would highly recommend utilizing the `async`/`await` pattern to separate background tasks and UI related code. If you are on 4.0, there is the `Bcl.Async` NuGet package from Microsoft that adds this functionality, where as it is baked into 4.5+. – Erik Jun 30 '14 at 04:44
2 Answers
No, you have to update the UIElement on the UI thread as the error says.
Yes, there other ways to run something on the UI thread other than using the Dispatcher
, but they like the Dispatcher
still run whatever it is you want to run on the UI thread - so will still freeze the UI.
If you are using C# 5 and .NET 4.5 or above you can easily run your long running process without blocking the UI Thread then when it completes continue on the UI thread (without worrying about how it works) using the async
and await
keywords:
private async Task<string> SimLongRunningProcessAsync()
{
await Task.Delay(2000);
return "Success";
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
button.Content = "Running...";
var result = await SimLongRunningProcessAsync();
button.Content = result;
}
If you do not have those however you will want to use the Dispatcher
. The Dispatcher
actually assists you running processes without freezing the UI
What you want to do is run the long running processes off the UI thread then when it is finished update the UI - which the Dispatcher
helps you to:
- Start long process on another thread and return immediately.
- (long process still running, UI continues to update)
- Long process finishes, update the UI on the UI thread.
e.g.:
private void UpdateButtonContent(string text)
{
button.Content = text;
}
private void SimLongRunningProcess()
{
Thread.Sleep(2000);
}
private void OnProcessFinished(Task task)
{
string content;
if(task.Exception != null)
{
content = task.Exception.Message;
}
else
{
content = "Success";
}
Dispatcher.BeginInvoke(new Action<string>(UpdateButtonContent), DispatcherPriority.Normal, content);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Start long running process and return immediatly
var task = Task.Factory.StartNew(SimLongRunningProcess);
task.ContinueWith(OnProcessFinished);
}

- 11,116
- 8
- 73
- 109
-
1The first example does not work because the Button_Click method is not async, therefore the await command cannot be used. – Jim Yarbro Aug 18 '17 at 10:08
-
@markmnl Your response with the use of `.NET 4.5 or later` is great. You solved my similar issue. Thank you for sharing your knowledge (and thus helping others). – nam Jul 24 '19 at 02:16
If you are using .NET 4.0 or newer, you can utilize the async
and await
keywords for clean, asynchronous code. This feature is built into 4.5 directly, and for 4.0 there is a NuGet package available from Microsoft (Microsoft.Bcl.Async
) to enable this functionality.
For example, a user clicks a button and you wish to do something that may take a bit of time, then report back to the user.
// Notice how this method is marked 'async', this allows the 'await' keyword
async void OnButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
button.IsEnabled = false;
button.Text = "Calculating...";
int result = await DoSomeWork();
button.IsEnabled = true;
button.Text = "Calculate";
}
// This is an asynchronous method that returns an integer result
Task<int> DoSomeWork()
{
// Do some lengthy computation here, will be run on a background thread
return 42;
}
Alternatively, you could use other mechanisms like the BackgroundWorker
class, or the Asynchronous Programming Model (APM) with callbacks. These are fine, however the async
/await
pattern is preferable.
If you have a choice, target .NET 4.5 (Win7+). If you must also support Windows XP, target .NET 4.0 and use the NuGet packages for Microsoft.Bcl.Async
.

- 12,730
- 5
- 36
- 42
-
The async and await keywords do not exist in .Net 4.0. They don't appear until .Net 4.5+ (can't press the bloody 'enter' key by itself to start a new line on this edit!) Sorry. Missed that detail about the NuGet package... but that won't be available Express editions. :( – Richard Robertson Jul 11 '15 at 18:19
-
I was using async event handlers and same error. My problem solved after I removed `.ConfigureAwait(false)` after the awaitable calls (e.g `int result = await DoSomeWork().ConfigureAwait(false);`. – Alisson Reinaldo Silva Jul 14 '16 at 00:41