I have a code like the following (I have stripped some code for readability)
private void RicercaArticoloStripped(object sender, DoWorkEventArgs e)
{
try
{
using (var context = new ControlloSchedeLocalEntities())
{
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text);
if (prodotti.Count() > 0)
{
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
{
textBlockDescrizioneArticolo.Text = prodotti.FirstOrDefault().WADESC;
}));
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error:\n\n" + ex.Message + "\r\nStack: " + ex.ToString());
}
}
private void textBoxCodiceArticolo_KeyUpStripped(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(RicercaArticoloStripped);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RicercaArticoloWorkerCompleted);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
object[] parameters = new object[] { textBoxCodiceArticolo.Text, textBlockDescrizioneArticolo.Text };
worker.RunWorkerAsync(parameters);
}
}
So, as for my understanding of BackgroundWorker, when I instantiate the:
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text);
I am doing it FROM the working thread, not the UI thread.
But I get an exception on the line immediately below, when I try to access the value:
if (prodotti.Count() > 0)
I get the (in)famous error:
“The calling thread cannot access this object because a different thread owns it”
Why?
As you already said you must use
Dispatcher.BeginInvoke/Invoketo perform operations from the control’s owner thread or you will get “The calling thread cannot access this object because a different thread owns it” exception. Thats why you got this exception;And here is why you got this exception on the line below (when
prodotti.Count()was called):When you create
prodottivariable it’s just aIEnumerable<T>object. So he actually calculates only when you call forprodotti.Count()method and thats why you got exception on this line.IEnumerableactually is generator, that means that he will produce new set of objects every time he used.To test this you can calculate
prodottias shown bellow:In this case you will get exception immediately because .ToList() forces all calculations.
Check this article for generators and enumerators: http://www.codeproject.com/Articles/155462/IEnumerable-Lazy-and-Dangerous
Updated:
really, when you use IEnumerable with reference types you can get the same objects as previously. Read this answer for more: https://stackoverflow.com/a/14361094/1467309