w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
Solving The calling thread cannot access this object because a different thread owns it Error Without Using Dispatcher

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 off 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 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:

  1. Start long process on another thread and return immediately.
  2. (long process still running, UI continues to update)
  3. 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);
    }




© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.