I've been working on a C# WinForm project that has a part in which when a user keys up "enter" button, a BackgroundWorker will set a new URI in the Source property of the Awesomium Instance. However, I'm encountering an AweInvalidOperationException ("The calling thread cannot access this object because a different thread owns it.").
Here's a sample code of a part of my work:
private void txt_To_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
backgroundWorker.RunWorkerAsync();
}
}
private void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
//Get values from an XML file and everything (Not included here anymore for it's too long)
awesomiumInstance.Source = new Uri("http://maps.google.com?saddr=" +
txt_From.Text.Replace(" ", "+") + "&daddr=" + txt_To.Text.Replace(" ", "+") + flag +
"&view=map&hl=en&doflg=ptk");
}
The AweInvalidOperationException happens at line 12
awesomiumInstance.Source = new Uri("http://maps.google.com?saddr=" +
txt_From.Text.Replace(" ", "+") + "&daddr=" +
txt_To.Text.Replace(" ", "+") + flag +
"&view=map&hl=en&doflg=ptk");
Here's the screenshot of the exception:
What could be the fix/solution to this exception?
You need to invoke the code on the UI Thread, since you are not using WPF you don't have the Dispatcher
, however you can try Invoke
or BeginInvoke
like the following
this.BeginInvoke((Action)(() =>
{
awesomiumInstance.Source = new Uri("http://maps.google.com?saddr=" +
txt_From.Text.Replace(" ", "+") + "&daddr=" +
txt_To.Text.Replace(" ", "+") + flag +
"&view=map&hl=en&doflg=ptk");
}));
Invoke
causes the action to execute on the thread that created the Control's window handle.
BeginInvoke
is the Asynchronous version of Invoke which means the thread will not block the caller as unlike the synchronous call which is blocking.
If that doesn't work you can then use the SynchronizationContext
EDIT: Post
is Asynchronous
SynchronizationContext.Current.Post(_ =>
{
awesomiumInstance.Source = new Uri("http://maps.google.com?saddr=" +
txt_From.Text.Replace(" ", "+") + "&daddr=" +
txt_To.Text.Replace(" ", "+") + flag +
"&view=map&hl=en&doflg=ptk");
}, null);
SynchronizationContext
assists you in executing code on the UI Thread where necessary, Delegates that are passed to its Send
or Post
method will then be invoked in that location. (Post is the non-blocking of Send.)
For a more detailed explanation please visit This Link
If SynchronizationContext.Current
is null then check this link when and when not it is null