The Calling Thread Cannot Access This Object Because a Different Thread Owns It.Wpf

The calling thread cannot access this object because a different thread owns it

This is a common problem with people getting started. Whenever you update your UI elements from a thread other than the main thread, you need to use:

this.Dispatcher.Invoke(() =>
{
...// your code here.
});

You can also use control.Dispatcher.CheckAccess() to check whether the current thread owns the control. If it does own it, your code looks as normal. Otherwise, use above pattern.

WPF: The calling thread cannot access this object because a different thread owns it

There are a lot of duplicates, all of which work and all of which say the same thing: You can't modify the UI from another thread. Displaying a messagebox does modify the UI. This restriction applies to all versions of Windows going back at least to Windows 95 and other OSs like Linux.

You don't need Invoke to update the UI or raw threads to perform anything in the background either. .NET allows you to execute work in the background with Task.Run, await its result and handle any exceptions. The only thing you need to write is :

private void SomeMethod()
{
...
}

private async void myButton_Click(object sender, RoutedEventArgs e)
{
try
{
await Task.Run(someMethod);
}
catch(Exception e)
{
ModernDialog.ShowMessage(e.ToString());
}
}

If you want to update the UI while processing in the background, eg to display progress, you can use the IProgress< T> as explained here, to report using any type as a message, eg int, string or a full class :

private void SomeMethod(IProgress<string> progress)
{
foreach(...)
{
progress.Report("foo");
....
}
}

private async void myButton_Click(object sender, RoutedEventArgs e)
{
var progressIndicator = new Progress<string>(reportProgressMethod);
try
{
await Task.Run(()=>someMethod(progressIndicator());
}
catch(Exception e)
{
ModernDialog.ShowMessage(e.ToString());
}
}

async void should only be used for event handlers. In all other cases, the method signature of an asynchronous method that doesn't return a result should be async Task

The Calling thread cannot access this object because a different thread owns it - WPF

A ui elememt can only be accessed by one UI Thread. CheckBox Requires UI Thread and your timer runs on different thread. Simple code to use Dispatcher

if (client.Connected == true)
{
Dispatcher.Invoke(()=> {
// Code causing the exception or requires UI thread access
CheckBox.IsChecked =true;
});
}

OR

if (client.Connected == true)
{
Dispatcher.Invoke(new Action(()=> {
// Code causing the exception or requires UI thread access
CheckBox.IsChecked =true;
}));
}

if you receive error An object reference is required for the non-static field, method, or property then use this

 Application.Current.Dispatcher.Invoke(() =>
{
// Code causing the exception or requires UI thread access
});

The calling Thread cannot access this object because a different thread owns it. Exception

Any access to a UI element, no matter if it is read or write, must be called through main UI thread. This thread is accessible through the Dispatcher.

In your code I see a line where this is not the case: when you are calling listBoxT2.SelectedValue

To fix the error call this code on the Dispatcher Thread and save it to a local variable:

int selectedValue;
listBoxT2.Dispatcher.Invoke(() => selectedValue = Convert.ToInt32(listBoxT2.SelectedValue));

The rest of the code should work fine.

C#: The calling thread cannot access this object because a different thread owns it

Try using

Application.Current.Dispatcher.Invoke

instead of

(MainWindow)System.Windows.Application.Current.MainWindow).pConnect.lbLine.Dispatcher.Invoke

The problem may be that the pConnect or lbLine is a UI object, so it, like any other UI object, cannot be used from other threads than the main thread.

Usually there is only one UI/Main thread, so all dispatchers or other ways to move execution to it will be equivalent.

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

  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);
}


Related Topics



Leave a reply



Submit