The calling thread cannot access this object because a different thread owns it
My code is as below
public CountryStandards()
{
InitializeComponent();
try
{
FillPageControls();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Country Standards", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// Fills the page controls.
/// </summary>
private void FillPageControls()
{
popUpProgressBar.IsOpen = true;
lblProgress.Content = "Loading. Please wait...";
progress.IsIndeterminate = true;
worker = new BackgroundWorker();
worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
GetGridData(null, 0); // filling grid
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
worker = null;
popUpProgressBar.IsOpen = false;
//filling Region dropdown
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_REGION";
DataSet dsRegionStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsRegionStandards, 0))
StandardsDefault.FillComboBox(cmbRegion, dsRegionStandards.Tables[0], "Region", "RegionId");
//filling Currency dropdown
objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_CURRENCY";
DataSet dsCurrencyStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCurrencyStandards, 0))
StandardsDefault.FillComboBox(cmbCurrency, dsCurrencyStandards.Tables[0], "CurrencyName", "CurrencyId");
if (Users.UserRole != "Admin")
btnSave.IsEnabled = false;
}
/// <summary>
/// Gets the grid data.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="pageIndex">Index of the page.( used in case of paging) </pamam>
private void GetGridData(object sender, int pageIndex)
{
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT";
objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
DataSet dsCountryStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCountryStandards, 0) && (chkbxMarketsSearch.IsChecked == true || chkbxBudgetsSearch.IsChecked == true || chkbxProgramsSearch.IsChecked == true))
{
DataTable objDataTable = StandardsDefault.FilterDatatableForModules(dsCountryStandards.Tables[0], "Country", chkbxMarketsSearch, chkbxBudgetsSearch, chkbxProgramsSearch);
dgCountryList.ItemsSource = objDataTable.DefaultView;
}
else
{
MessageBox.Show("No Records Found", "Country Standards", MessageBoxButton.OK, MessageBoxImage.Information);
btnClear_Click(null, null);
}
}
The step objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
in get grid data throws exception
The calling thread cannot access this object because a different
thread owns it.
What's wrong here?
c# wpf multithreading backgroundworker
add a comment |
My code is as below
public CountryStandards()
{
InitializeComponent();
try
{
FillPageControls();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Country Standards", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// Fills the page controls.
/// </summary>
private void FillPageControls()
{
popUpProgressBar.IsOpen = true;
lblProgress.Content = "Loading. Please wait...";
progress.IsIndeterminate = true;
worker = new BackgroundWorker();
worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
GetGridData(null, 0); // filling grid
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
worker = null;
popUpProgressBar.IsOpen = false;
//filling Region dropdown
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_REGION";
DataSet dsRegionStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsRegionStandards, 0))
StandardsDefault.FillComboBox(cmbRegion, dsRegionStandards.Tables[0], "Region", "RegionId");
//filling Currency dropdown
objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_CURRENCY";
DataSet dsCurrencyStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCurrencyStandards, 0))
StandardsDefault.FillComboBox(cmbCurrency, dsCurrencyStandards.Tables[0], "CurrencyName", "CurrencyId");
if (Users.UserRole != "Admin")
btnSave.IsEnabled = false;
}
/// <summary>
/// Gets the grid data.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="pageIndex">Index of the page.( used in case of paging) </pamam>
private void GetGridData(object sender, int pageIndex)
{
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT";
objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
DataSet dsCountryStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCountryStandards, 0) && (chkbxMarketsSearch.IsChecked == true || chkbxBudgetsSearch.IsChecked == true || chkbxProgramsSearch.IsChecked == true))
{
DataTable objDataTable = StandardsDefault.FilterDatatableForModules(dsCountryStandards.Tables[0], "Country", chkbxMarketsSearch, chkbxBudgetsSearch, chkbxProgramsSearch);
dgCountryList.ItemsSource = objDataTable.DefaultView;
}
else
{
MessageBox.Show("No Records Found", "Country Standards", MessageBoxButton.OK, MessageBoxImage.Information);
btnClear_Click(null, null);
}
}
The step objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
in get grid data throws exception
The calling thread cannot access this object because a different
thread owns it.
What's wrong here?
c# wpf multithreading backgroundworker
4
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21
add a comment |
My code is as below
public CountryStandards()
{
InitializeComponent();
try
{
FillPageControls();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Country Standards", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// Fills the page controls.
/// </summary>
private void FillPageControls()
{
popUpProgressBar.IsOpen = true;
lblProgress.Content = "Loading. Please wait...";
progress.IsIndeterminate = true;
worker = new BackgroundWorker();
worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
GetGridData(null, 0); // filling grid
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
worker = null;
popUpProgressBar.IsOpen = false;
//filling Region dropdown
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_REGION";
DataSet dsRegionStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsRegionStandards, 0))
StandardsDefault.FillComboBox(cmbRegion, dsRegionStandards.Tables[0], "Region", "RegionId");
//filling Currency dropdown
objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_CURRENCY";
DataSet dsCurrencyStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCurrencyStandards, 0))
StandardsDefault.FillComboBox(cmbCurrency, dsCurrencyStandards.Tables[0], "CurrencyName", "CurrencyId");
if (Users.UserRole != "Admin")
btnSave.IsEnabled = false;
}
/// <summary>
/// Gets the grid data.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="pageIndex">Index of the page.( used in case of paging) </pamam>
private void GetGridData(object sender, int pageIndex)
{
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT";
objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
DataSet dsCountryStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCountryStandards, 0) && (chkbxMarketsSearch.IsChecked == true || chkbxBudgetsSearch.IsChecked == true || chkbxProgramsSearch.IsChecked == true))
{
DataTable objDataTable = StandardsDefault.FilterDatatableForModules(dsCountryStandards.Tables[0], "Country", chkbxMarketsSearch, chkbxBudgetsSearch, chkbxProgramsSearch);
dgCountryList.ItemsSource = objDataTable.DefaultView;
}
else
{
MessageBox.Show("No Records Found", "Country Standards", MessageBoxButton.OK, MessageBoxImage.Information);
btnClear_Click(null, null);
}
}
The step objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
in get grid data throws exception
The calling thread cannot access this object because a different
thread owns it.
What's wrong here?
c# wpf multithreading backgroundworker
My code is as below
public CountryStandards()
{
InitializeComponent();
try
{
FillPageControls();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Country Standards", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// Fills the page controls.
/// </summary>
private void FillPageControls()
{
popUpProgressBar.IsOpen = true;
lblProgress.Content = "Loading. Please wait...";
progress.IsIndeterminate = true;
worker = new BackgroundWorker();
worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
GetGridData(null, 0); // filling grid
}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
worker = null;
popUpProgressBar.IsOpen = false;
//filling Region dropdown
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_REGION";
DataSet dsRegionStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsRegionStandards, 0))
StandardsDefault.FillComboBox(cmbRegion, dsRegionStandards.Tables[0], "Region", "RegionId");
//filling Currency dropdown
objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT_CURRENCY";
DataSet dsCurrencyStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCurrencyStandards, 0))
StandardsDefault.FillComboBox(cmbCurrency, dsCurrencyStandards.Tables[0], "CurrencyName", "CurrencyId");
if (Users.UserRole != "Admin")
btnSave.IsEnabled = false;
}
/// <summary>
/// Gets the grid data.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="pageIndex">Index of the page.( used in case of paging) </pamam>
private void GetGridData(object sender, int pageIndex)
{
Standards.UDMCountryStandards objUDMCountryStandards = new Standards.UDMCountryStandards();
objUDMCountryStandards.Operation = "SELECT";
objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
DataSet dsCountryStandards = objStandardsBusinessLayer.GetCountryStandards(objUDMCountryStandards);
if (!StandardsDefault.IsNullOrEmptyDataTable(dsCountryStandards, 0) && (chkbxMarketsSearch.IsChecked == true || chkbxBudgetsSearch.IsChecked == true || chkbxProgramsSearch.IsChecked == true))
{
DataTable objDataTable = StandardsDefault.FilterDatatableForModules(dsCountryStandards.Tables[0], "Country", chkbxMarketsSearch, chkbxBudgetsSearch, chkbxProgramsSearch);
dgCountryList.ItemsSource = objDataTable.DefaultView;
}
else
{
MessageBox.Show("No Records Found", "Country Standards", MessageBoxButton.OK, MessageBoxImage.Information);
btnClear_Click(null, null);
}
}
The step objUDMCountryStandards.Country = txtSearchCountry.Text.Trim() != string.Empty ? txtSearchCountry.Text : null;
in get grid data throws exception
The calling thread cannot access this object because a different
thread owns it.
What's wrong here?
c# wpf multithreading backgroundworker
c# wpf multithreading backgroundworker
edited Dec 1 '15 at 21:27
Christos
44.4k84678
44.4k84678
asked Mar 16 '12 at 6:07
Kuntady NitheshKuntady Nithesh
4,403124982
4,403124982
4
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21
add a comment |
4
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21
4
4
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21
add a comment |
13 Answers
13
active
oldest
votes
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.
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer
– JumpingJezza
Aug 21 '15 at 2:59
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
|
show 3 more comments
Another good use for Dispatcher.Invoke
is for immediately updating the UI in a function that performs other tasks:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
I use this to update button text to "Processing..." and disable it while making WebClient
requests.
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
add a comment |
To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
.
The point is that you have to call Invoke()
of the Dispatcher
of the control that you're trying to access, which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher
. So instead you should use YourControl.Dispatcher.Invoke()
to be safe. I was banging my head for a couple of hours before I realized this.
Update
For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. WPF engine will marshal cross-thread calls on the correct UI thread. See more details here. Thanks to @aaronburro for the info and link. You may also want to read our conversation below in comments.
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its ownDispatcher
. In those cases (which are admittedly rare), callingControl.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).
– dotNET
Sep 27 '16 at 10:13
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
|
show 15 more comments
If anyone tries to work with BitmapSource
in WPF and threads and has this same message: just call Freeze()
method first before passing a BitmapSource
as a thread parameter.
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
add a comment |
this happened with me because I tried to access UI
component in another thread insted of UI thread
like this
private void button_Click(object sender, RoutedEventArgs e)
{
new Thread(SyncProcces).Start();
}
private void SyncProcces()
{
string val1 = null, val2 = null;
//here is the problem
val1 = textBox1.Text;//access UI in another thread
val2 = textBox2.Text;//access UI in another thread
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2);
}
to solve this problem, wrap any ui call inside what Candide mentioned above in his answer
private void SyncProcces()
{
string val1 = null, val2 = null;
this.Dispatcher.Invoke((Action)(() =>
{//this refer to form in WPF application
val1 = textBox.Text;
val2 = textBox_Copy.Text;
}));
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2 );
}
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
add a comment |
You need to Update in to the UI, So use
Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)}));
add a comment |
For some reason Candide's answer didn't build. It was helpful, though, as it led me to find this, which worked perfectly:
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
//your code here...
}));
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
If it worked for you, it was unnecessary to use it in the first place.System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, useSystem.Windows.Application.Current.Dispatcher
.
– Will
Sep 1 '17 at 14:46
add a comment |
I also found that System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
is not always dispatcher of target control, just as dotNet wrote in his answer. I didn't had access to control's own dispatcher, so I used Application.Current.Dispatcher
and it solved the problem.
add a comment |
The problem is that you are calling GetGridData
from a background thread. This method accesses several WPF controls which are bound to the main thread. Any attempt to access them from a background thread will lead to this error.
In order to get back to the correct thread you should use SynchronizationContext.Current.Post
. However in this particular case it seems like the majority of the work you are doing is UI based. Hence you would be creating a background thread just to go immediately back to the UI thread and do some work. You need to refactor your code a bit so that it can do the expensive work on the background thread and then post the new data to the UI thread afterwards
add a comment |
As mentioned here, Dispatcher.Invoke
could freeze the UI. Should use Dispatcher.BeginInvoke
instead.
Here is a handy extension class to simplify the checking and calling dispatcher invocation.
Sample usage: (call from WPF window)
this Dispatcher.InvokeIfRequired(new Action(() =>
{
logTextbox.AppendText(message);
logTextbox.ScrollToEnd();
}));
Extension class:
using System;
using System.Windows.Threading;
namespace WpfUtility
{
public static class DispatcherExtension
{
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
return;
}
action();
}
}
}
add a comment |
This works for me.
new Thread(() =>
{
Thread.CurrentThread.IsBackground = false;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {
//Your Code here.
}, null);
}).Start();
add a comment |
Also, another solution is ensuring your controls are created in UI thread, not by a background worker thread for example.
add a comment |
I kept getting the error when I added cascading comboboxes to my WPF application, and resolved the error by using this API:
using System.Windows.Data;
private readonly object _lock = new object();
private CustomObservableCollection<string> _myUiBoundProperty;
public CustomObservableCollection<string> MyUiBoundProperty
{
get { return _myUiBoundProperty; }
set
{
if (value == _myUiBoundProperty) return;
_myUiBoundProperty = value;
NotifyPropertyChanged(nameof(MyUiBoundProperty));
}
}
public MyViewModelCtor(INavigationService navigationService)
{
// Other code...
BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );
}
For details, please see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Windows.Data.BindingOperations.EnableCollectionSynchronization);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7);k(DevLang-csharp)&rd=true
add a comment |
protected by Community♦ Apr 17 '17 at 17:18
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
13 Answers
13
active
oldest
votes
13 Answers
13
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer
– JumpingJezza
Aug 21 '15 at 2:59
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
|
show 3 more comments
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.
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer
– JumpingJezza
Aug 21 '15 at 2:59
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
|
show 3 more comments
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.
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.
edited Feb 12 '17 at 0:18


oddRaven
345417
345417
answered Mar 16 '12 at 6:22
CandideCandide
24k64651
24k64651
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer
– JumpingJezza
Aug 21 '15 at 2:59
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
|
show 3 more comments
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer
– JumpingJezza
Aug 21 '15 at 2:59
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
3
3
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
I have the same problem as OP; My problem now is that the event causes now a stack overflow. :
– Malavos
Jan 22 '14 at 12:14
1
1
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
Went back to my old project and solved this. Also, I had forgotten to +1 this. This method works quite well! It improve my application loading time on 10seconds or even more, just by using threads to load our localized resources. Cheers!
– Malavos
May 7 '14 at 13:21
3
3
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
If I'm not wrong you can't even read a UI object from a non-owner thread; surprised me a bit.
– Elliot
Mar 2 '15 at 9:25
22
22
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer– JumpingJezza
Aug 21 '15 at 2:59
Application.Current.Dispatcher.Invoke(MyMethod, DispatcherPriority.ContextIdle);
to get the dispatcher if not on the UI thread as per this answer– JumpingJezza
Aug 21 '15 at 2:59
2
2
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
@Candide am still getting this error
– Meer
May 7 '16 at 6:13
|
show 3 more comments
Another good use for Dispatcher.Invoke
is for immediately updating the UI in a function that performs other tasks:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
I use this to update button text to "Processing..." and disable it while making WebClient
requests.
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
add a comment |
Another good use for Dispatcher.Invoke
is for immediately updating the UI in a function that performs other tasks:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
I use this to update button text to "Processing..." and disable it while making WebClient
requests.
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
add a comment |
Another good use for Dispatcher.Invoke
is for immediately updating the UI in a function that performs other tasks:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
I use this to update button text to "Processing..." and disable it while making WebClient
requests.
Another good use for Dispatcher.Invoke
is for immediately updating the UI in a function that performs other tasks:
// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);
I use this to update button text to "Processing..." and disable it while making WebClient
requests.
edited Jan 12 '18 at 4:37


Lauraducky
539823
539823
answered Jun 17 '14 at 19:03


computerGuyCJcomputerGuyCJ
63058
63058
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
add a comment |
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
4
4
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This answer is being discussed on Meta. meta.stackoverflow.com/questions/361844/…
– JDB
Jan 12 '18 at 15:56
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
This stopped my control from getting data from internet?
– user4350912
Mar 6 '18 at 16:50
add a comment |
To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
.
The point is that you have to call Invoke()
of the Dispatcher
of the control that you're trying to access, which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher
. So instead you should use YourControl.Dispatcher.Invoke()
to be safe. I was banging my head for a couple of hours before I realized this.
Update
For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. WPF engine will marshal cross-thread calls on the correct UI thread. See more details here. Thanks to @aaronburro for the info and link. You may also want to read our conversation below in comments.
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its ownDispatcher
. In those cases (which are admittedly rare), callingControl.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).
– dotNET
Sep 27 '16 at 10:13
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
|
show 15 more comments
To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
.
The point is that you have to call Invoke()
of the Dispatcher
of the control that you're trying to access, which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher
. So instead you should use YourControl.Dispatcher.Invoke()
to be safe. I was banging my head for a couple of hours before I realized this.
Update
For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. WPF engine will marshal cross-thread calls on the correct UI thread. See more details here. Thanks to @aaronburro for the info and link. You may also want to read our conversation below in comments.
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its ownDispatcher
. In those cases (which are admittedly rare), callingControl.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).
– dotNET
Sep 27 '16 at 10:13
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
|
show 15 more comments
To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
.
The point is that you have to call Invoke()
of the Dispatcher
of the control that you're trying to access, which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher
. So instead you should use YourControl.Dispatcher.Invoke()
to be safe. I was banging my head for a couple of hours before I realized this.
Update
For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. WPF engine will marshal cross-thread calls on the correct UI thread. See more details here. Thanks to @aaronburro for the info and link. You may also want to read our conversation below in comments.
To add my 2 cents, the exception can occur even if you call your code through System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
.
The point is that you have to call Invoke()
of the Dispatcher
of the control that you're trying to access, which in some cases may not be the same as System.Windows.Threading.Dispatcher.CurrentDispatcher
. So instead you should use YourControl.Dispatcher.Invoke()
to be safe. I was banging my head for a couple of hours before I realized this.
Update
For future readers, it looks like this has changed in the newer versions of .NET (4.0 and above). Now you no longer have to worry about the correct dispatcher when updating UI-backing properties in your VM. WPF engine will marshal cross-thread calls on the correct UI thread. See more details here. Thanks to @aaronburro for the info and link. You may also want to read our conversation below in comments.
edited Mar 26 at 18:15
answered Oct 21 '15 at 4:31


dotNETdotNET
18.3k1387148
18.3k1387148
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its ownDispatcher
. In those cases (which are admittedly rare), callingControl.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).
– dotNET
Sep 27 '16 at 10:13
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
|
show 15 more comments
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its ownDispatcher
. In those cases (which are admittedly rare), callingControl.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).
– dotNET
Sep 27 '16 at 10:13
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
4
4
@l33t: WPF supports multiple UI threads in one application, each of which will have its own
Dispatcher
. In those cases (which are admittedly rare), calling Control.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).– dotNET
Sep 27 '16 at 10:13
@l33t: WPF supports multiple UI threads in one application, each of which will have its own
Dispatcher
. In those cases (which are admittedly rare), calling Control.Dispatcher
is the safe approach. For reference you can see this article as well as this SO post (particularly Squidward's answer).– dotNET
Sep 27 '16 at 10:13
1
1
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
Interestingly, I was facing this very exception when I googled and landed on this page and like most of us do, tried the highest voted answer, which didn't solve my issue then. I then found out this reason and posted it here for peer developers.
– dotNET
Sep 27 '16 at 10:15
1
1
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
@l33t, if you are using MVVM correctly, then it shouldn't be a problem. The view necessarily know what Dispatcher it is using, whilehe ViewModels and Models know nothing of controls and have no need to know of controls.
– aaronburro
Feb 23 '18 at 14:54
1
1
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
@aaronburro: Problem is that VM may want to launch actions on alternate threads (e.g. Tasks, Timer-based actions, Parallel queries), and as the operation progresses, may like to update UI (through RaisePropertyChanged etc), which will in turn try to access a UI control from non-UI thread and thus result in this exception. I don't know of a correct MVVM approach that would solve this problem.
– dotNET
Feb 24 '18 at 8:39
1
1
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
The WPF binding engine automatically marshals property change events to the correct Dispatcher. This is why VM has no need to know of the Dispatcher; all it has to do is just raise property changed events. WinForms binding is a different story.
– aaronburro
Aug 17 '18 at 20:31
|
show 15 more comments
If anyone tries to work with BitmapSource
in WPF and threads and has this same message: just call Freeze()
method first before passing a BitmapSource
as a thread parameter.
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
add a comment |
If anyone tries to work with BitmapSource
in WPF and threads and has this same message: just call Freeze()
method first before passing a BitmapSource
as a thread parameter.
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
add a comment |
If anyone tries to work with BitmapSource
in WPF and threads and has this same message: just call Freeze()
method first before passing a BitmapSource
as a thread parameter.
If anyone tries to work with BitmapSource
in WPF and threads and has this same message: just call Freeze()
method first before passing a BitmapSource
as a thread parameter.
edited Apr 23 '18 at 8:59


Hakam Fostok
5,72284470
5,72284470
answered Nov 25 '15 at 12:59
juFojuFo
10.9k761110
10.9k761110
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
add a comment |
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
15
15
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
Ah, nothing like a good old vague and mysterious trick to solve something nobody understands.
– Edwin
Mar 4 '17 at 10:43
1
1
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
I'd love more information about why this works and how I could have figured it out myself.
– Xavier Shay
Feb 28 '18 at 17:45
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
@XavierShay docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
– juFo
Mar 1 '18 at 10:36
add a comment |
this happened with me because I tried to access UI
component in another thread insted of UI thread
like this
private void button_Click(object sender, RoutedEventArgs e)
{
new Thread(SyncProcces).Start();
}
private void SyncProcces()
{
string val1 = null, val2 = null;
//here is the problem
val1 = textBox1.Text;//access UI in another thread
val2 = textBox2.Text;//access UI in another thread
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2);
}
to solve this problem, wrap any ui call inside what Candide mentioned above in his answer
private void SyncProcces()
{
string val1 = null, val2 = null;
this.Dispatcher.Invoke((Action)(() =>
{//this refer to form in WPF application
val1 = textBox.Text;
val2 = textBox_Copy.Text;
}));
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2 );
}
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
add a comment |
this happened with me because I tried to access UI
component in another thread insted of UI thread
like this
private void button_Click(object sender, RoutedEventArgs e)
{
new Thread(SyncProcces).Start();
}
private void SyncProcces()
{
string val1 = null, val2 = null;
//here is the problem
val1 = textBox1.Text;//access UI in another thread
val2 = textBox2.Text;//access UI in another thread
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2);
}
to solve this problem, wrap any ui call inside what Candide mentioned above in his answer
private void SyncProcces()
{
string val1 = null, val2 = null;
this.Dispatcher.Invoke((Action)(() =>
{//this refer to form in WPF application
val1 = textBox.Text;
val2 = textBox_Copy.Text;
}));
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2 );
}
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
add a comment |
this happened with me because I tried to access UI
component in another thread insted of UI thread
like this
private void button_Click(object sender, RoutedEventArgs e)
{
new Thread(SyncProcces).Start();
}
private void SyncProcces()
{
string val1 = null, val2 = null;
//here is the problem
val1 = textBox1.Text;//access UI in another thread
val2 = textBox2.Text;//access UI in another thread
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2);
}
to solve this problem, wrap any ui call inside what Candide mentioned above in his answer
private void SyncProcces()
{
string val1 = null, val2 = null;
this.Dispatcher.Invoke((Action)(() =>
{//this refer to form in WPF application
val1 = textBox.Text;
val2 = textBox_Copy.Text;
}));
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2 );
}
this happened with me because I tried to access UI
component in another thread insted of UI thread
like this
private void button_Click(object sender, RoutedEventArgs e)
{
new Thread(SyncProcces).Start();
}
private void SyncProcces()
{
string val1 = null, val2 = null;
//here is the problem
val1 = textBox1.Text;//access UI in another thread
val2 = textBox2.Text;//access UI in another thread
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2);
}
to solve this problem, wrap any ui call inside what Candide mentioned above in his answer
private void SyncProcces()
{
string val1 = null, val2 = null;
this.Dispatcher.Invoke((Action)(() =>
{//this refer to form in WPF application
val1 = textBox.Text;
val2 = textBox_Copy.Text;
}));
localStore = new LocalStore(val1);
remoteStore = new RemoteStore(val2 );
}
edited May 23 '17 at 12:02
Community♦
11
11
answered Jun 27 '16 at 7:59


Basheer AL-MOMANIBasheer AL-MOMANI
6,98814866
6,98814866
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
add a comment |
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
1
1
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvoted, because this is not a duplicate answer or plagiaristic, but it instead provides a good example that other answers were lacking, while giving credit for what was posted earlier.
– Panzercrisis
Sep 2 '16 at 15:24
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
Upvote is for a clear answer. Although same was written by others, but this make it clear for anyone who is stuck.
– NishantM
Mar 4 '17 at 7:11
add a comment |
You need to Update in to the UI, So use
Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)}));
add a comment |
You need to Update in to the UI, So use
Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)}));
add a comment |
You need to Update in to the UI, So use
Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)}));
You need to Update in to the UI, So use
Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)}));
edited Mar 5 '13 at 12:02
Taryn♦
193k47295358
193k47295358
answered Mar 5 '13 at 11:27
VikramBoseVikramBose
193110
193110
add a comment |
add a comment |
For some reason Candide's answer didn't build. It was helpful, though, as it led me to find this, which worked perfectly:
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
//your code here...
}));
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
If it worked for you, it was unnecessary to use it in the first place.System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, useSystem.Windows.Application.Current.Dispatcher
.
– Will
Sep 1 '17 at 14:46
add a comment |
For some reason Candide's answer didn't build. It was helpful, though, as it led me to find this, which worked perfectly:
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
//your code here...
}));
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
If it worked for you, it was unnecessary to use it in the first place.System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, useSystem.Windows.Application.Current.Dispatcher
.
– Will
Sep 1 '17 at 14:46
add a comment |
For some reason Candide's answer didn't build. It was helpful, though, as it led me to find this, which worked perfectly:
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
//your code here...
}));
For some reason Candide's answer didn't build. It was helpful, though, as it led me to find this, which worked perfectly:
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
//your code here...
}));
answered Jul 12 '15 at 10:44


SarahSarah
168126
168126
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
If it worked for you, it was unnecessary to use it in the first place.System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, useSystem.Windows.Application.Current.Dispatcher
.
– Will
Sep 1 '17 at 14:46
add a comment |
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
If it worked for you, it was unnecessary to use it in the first place.System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, useSystem.Windows.Application.Current.Dispatcher
.
– Will
Sep 1 '17 at 14:46
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
It's possible that you didn't call from the form's class. Either you can grab a reference to the Window, or you can probably use what you suggested.
– Simone
Nov 12 '15 at 11:05
4
4
If it worked for you, it was unnecessary to use it in the first place.
System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, use System.Windows.Application.Current.Dispatcher
.– Will
Sep 1 '17 at 14:46
If it worked for you, it was unnecessary to use it in the first place.
System.Windows.Threading.Dispatcher.CurrentDispatcher
is the dispatcher for the current thread. That means if you're on a background thread, it's not going to be the UI thread's dispatcher. To access the UI thread's dispatcher, use System.Windows.Application.Current.Dispatcher
.– Will
Sep 1 '17 at 14:46
add a comment |
I also found that System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
is not always dispatcher of target control, just as dotNet wrote in his answer. I didn't had access to control's own dispatcher, so I used Application.Current.Dispatcher
and it solved the problem.
add a comment |
I also found that System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
is not always dispatcher of target control, just as dotNet wrote in his answer. I didn't had access to control's own dispatcher, so I used Application.Current.Dispatcher
and it solved the problem.
add a comment |
I also found that System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
is not always dispatcher of target control, just as dotNet wrote in his answer. I didn't had access to control's own dispatcher, so I used Application.Current.Dispatcher
and it solved the problem.
I also found that System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke()
is not always dispatcher of target control, just as dotNet wrote in his answer. I didn't had access to control's own dispatcher, so I used Application.Current.Dispatcher
and it solved the problem.
answered May 11 '17 at 11:45
Paulus LimmaPaulus Limma
8516
8516
add a comment |
add a comment |
The problem is that you are calling GetGridData
from a background thread. This method accesses several WPF controls which are bound to the main thread. Any attempt to access them from a background thread will lead to this error.
In order to get back to the correct thread you should use SynchronizationContext.Current.Post
. However in this particular case it seems like the majority of the work you are doing is UI based. Hence you would be creating a background thread just to go immediately back to the UI thread and do some work. You need to refactor your code a bit so that it can do the expensive work on the background thread and then post the new data to the UI thread afterwards
add a comment |
The problem is that you are calling GetGridData
from a background thread. This method accesses several WPF controls which are bound to the main thread. Any attempt to access them from a background thread will lead to this error.
In order to get back to the correct thread you should use SynchronizationContext.Current.Post
. However in this particular case it seems like the majority of the work you are doing is UI based. Hence you would be creating a background thread just to go immediately back to the UI thread and do some work. You need to refactor your code a bit so that it can do the expensive work on the background thread and then post the new data to the UI thread afterwards
add a comment |
The problem is that you are calling GetGridData
from a background thread. This method accesses several WPF controls which are bound to the main thread. Any attempt to access them from a background thread will lead to this error.
In order to get back to the correct thread you should use SynchronizationContext.Current.Post
. However in this particular case it seems like the majority of the work you are doing is UI based. Hence you would be creating a background thread just to go immediately back to the UI thread and do some work. You need to refactor your code a bit so that it can do the expensive work on the background thread and then post the new data to the UI thread afterwards
The problem is that you are calling GetGridData
from a background thread. This method accesses several WPF controls which are bound to the main thread. Any attempt to access them from a background thread will lead to this error.
In order to get back to the correct thread you should use SynchronizationContext.Current.Post
. However in this particular case it seems like the majority of the work you are doing is UI based. Hence you would be creating a background thread just to go immediately back to the UI thread and do some work. You need to refactor your code a bit so that it can do the expensive work on the background thread and then post the new data to the UI thread afterwards
answered Mar 16 '12 at 6:18
JaredParJaredPar
581k12110751354
581k12110751354
add a comment |
add a comment |
As mentioned here, Dispatcher.Invoke
could freeze the UI. Should use Dispatcher.BeginInvoke
instead.
Here is a handy extension class to simplify the checking and calling dispatcher invocation.
Sample usage: (call from WPF window)
this Dispatcher.InvokeIfRequired(new Action(() =>
{
logTextbox.AppendText(message);
logTextbox.ScrollToEnd();
}));
Extension class:
using System;
using System.Windows.Threading;
namespace WpfUtility
{
public static class DispatcherExtension
{
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
return;
}
action();
}
}
}
add a comment |
As mentioned here, Dispatcher.Invoke
could freeze the UI. Should use Dispatcher.BeginInvoke
instead.
Here is a handy extension class to simplify the checking and calling dispatcher invocation.
Sample usage: (call from WPF window)
this Dispatcher.InvokeIfRequired(new Action(() =>
{
logTextbox.AppendText(message);
logTextbox.ScrollToEnd();
}));
Extension class:
using System;
using System.Windows.Threading;
namespace WpfUtility
{
public static class DispatcherExtension
{
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
return;
}
action();
}
}
}
add a comment |
As mentioned here, Dispatcher.Invoke
could freeze the UI. Should use Dispatcher.BeginInvoke
instead.
Here is a handy extension class to simplify the checking and calling dispatcher invocation.
Sample usage: (call from WPF window)
this Dispatcher.InvokeIfRequired(new Action(() =>
{
logTextbox.AppendText(message);
logTextbox.ScrollToEnd();
}));
Extension class:
using System;
using System.Windows.Threading;
namespace WpfUtility
{
public static class DispatcherExtension
{
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
return;
}
action();
}
}
}
As mentioned here, Dispatcher.Invoke
could freeze the UI. Should use Dispatcher.BeginInvoke
instead.
Here is a handy extension class to simplify the checking and calling dispatcher invocation.
Sample usage: (call from WPF window)
this Dispatcher.InvokeIfRequired(new Action(() =>
{
logTextbox.AppendText(message);
logTextbox.ScrollToEnd();
}));
Extension class:
using System;
using System.Windows.Threading;
namespace WpfUtility
{
public static class DispatcherExtension
{
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher == null)
{
return;
}
if (!dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
return;
}
action();
}
}
}
edited Mar 29 '18 at 12:53
answered Mar 28 '18 at 22:23
Jeson MartajayaJeson Martajaya
4,35563644
4,35563644
add a comment |
add a comment |
This works for me.
new Thread(() =>
{
Thread.CurrentThread.IsBackground = false;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {
//Your Code here.
}, null);
}).Start();
add a comment |
This works for me.
new Thread(() =>
{
Thread.CurrentThread.IsBackground = false;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {
//Your Code here.
}, null);
}).Start();
add a comment |
This works for me.
new Thread(() =>
{
Thread.CurrentThread.IsBackground = false;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {
//Your Code here.
}, null);
}).Start();
This works for me.
new Thread(() =>
{
Thread.CurrentThread.IsBackground = false;
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {
//Your Code here.
}, null);
}).Start();
edited Dec 26 '18 at 3:19
answered Jun 15 '18 at 15:41
nPcompnPcomp
3,10211929
3,10211929
add a comment |
add a comment |
Also, another solution is ensuring your controls are created in UI thread, not by a background worker thread for example.
add a comment |
Also, another solution is ensuring your controls are created in UI thread, not by a background worker thread for example.
add a comment |
Also, another solution is ensuring your controls are created in UI thread, not by a background worker thread for example.
Also, another solution is ensuring your controls are created in UI thread, not by a background worker thread for example.
answered Feb 23 '17 at 8:27
FindOutIslamNowFindOutIslamNow
3561417
3561417
add a comment |
add a comment |
I kept getting the error when I added cascading comboboxes to my WPF application, and resolved the error by using this API:
using System.Windows.Data;
private readonly object _lock = new object();
private CustomObservableCollection<string> _myUiBoundProperty;
public CustomObservableCollection<string> MyUiBoundProperty
{
get { return _myUiBoundProperty; }
set
{
if (value == _myUiBoundProperty) return;
_myUiBoundProperty = value;
NotifyPropertyChanged(nameof(MyUiBoundProperty));
}
}
public MyViewModelCtor(INavigationService navigationService)
{
// Other code...
BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );
}
For details, please see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Windows.Data.BindingOperations.EnableCollectionSynchronization);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7);k(DevLang-csharp)&rd=true
add a comment |
I kept getting the error when I added cascading comboboxes to my WPF application, and resolved the error by using this API:
using System.Windows.Data;
private readonly object _lock = new object();
private CustomObservableCollection<string> _myUiBoundProperty;
public CustomObservableCollection<string> MyUiBoundProperty
{
get { return _myUiBoundProperty; }
set
{
if (value == _myUiBoundProperty) return;
_myUiBoundProperty = value;
NotifyPropertyChanged(nameof(MyUiBoundProperty));
}
}
public MyViewModelCtor(INavigationService navigationService)
{
// Other code...
BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );
}
For details, please see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Windows.Data.BindingOperations.EnableCollectionSynchronization);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7);k(DevLang-csharp)&rd=true
add a comment |
I kept getting the error when I added cascading comboboxes to my WPF application, and resolved the error by using this API:
using System.Windows.Data;
private readonly object _lock = new object();
private CustomObservableCollection<string> _myUiBoundProperty;
public CustomObservableCollection<string> MyUiBoundProperty
{
get { return _myUiBoundProperty; }
set
{
if (value == _myUiBoundProperty) return;
_myUiBoundProperty = value;
NotifyPropertyChanged(nameof(MyUiBoundProperty));
}
}
public MyViewModelCtor(INavigationService navigationService)
{
// Other code...
BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );
}
For details, please see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Windows.Data.BindingOperations.EnableCollectionSynchronization);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7);k(DevLang-csharp)&rd=true
I kept getting the error when I added cascading comboboxes to my WPF application, and resolved the error by using this API:
using System.Windows.Data;
private readonly object _lock = new object();
private CustomObservableCollection<string> _myUiBoundProperty;
public CustomObservableCollection<string> MyUiBoundProperty
{
get { return _myUiBoundProperty; }
set
{
if (value == _myUiBoundProperty) return;
_myUiBoundProperty = value;
NotifyPropertyChanged(nameof(MyUiBoundProperty));
}
}
public MyViewModelCtor(INavigationService navigationService)
{
// Other code...
BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );
}
For details, please see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(System.Windows.Data.BindingOperations.EnableCollectionSynchronization);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7);k(DevLang-csharp)&rd=true
answered Jun 15 '18 at 19:00
user8128167user8128167
2,82053652
2,82053652
add a comment |
add a comment |
protected by Community♦ Apr 17 '17 at 17:18
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
4
possible duplicate of stackoverflow.com/questions/2728896/… , stackoverflow.com/questions/3146942/… , stackoverflow.com/questions/7684206/… , stackoverflow.com/questions/8950347/…
– user166390
Mar 16 '12 at 6:21