我有一个类似下面的代码(为了便于阅读,我删除了一些代码)
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);
}
}
所以,至于我对BackgroundWorker的理解,当我实例化时: var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text);
我是从工作线程而不是UI线程做的。
但是当我尝试访问该值时,我在下面的行上遇到异常: if(prodotti.Count()> 0)
我得到(in)着名的错误: “调用线程无法访问此对象,因为其他线程拥有它”
为什么?
答案 0 :(得分:0)
如前所述,您必须使用Dispatcher.BeginInvoke/Invoke
从控件的所有者线程执行操作,否则您将获得“调用线程无法访问此对象,因为另一个线程拥有它”异常。这就是你得到这个例外的原因;
这就是为什么你在下面这行(调用prodotti.Count()
时)得到这个例外的原因:
创建prodotti
变量时,它只是一个IEnumerable<T>
对象。所以他实际上只在你调用prodotti.Count()
方法时进行计算,这就是为什么你在这一行上得到例外。
IEnumerable
实际上是生成器,这意味着他每次使用时都会生成新的对象集。
要测试此项,您可以计算prodotti
,如下所示:
var prodotti = context.VProdotti.Where(i => i.WACMAT == textBoxCodiceArticolo.Text).ToList();
在这种情况下,您将立即获得异常,因为.ToList()会强制进行所有计算。
查看本文中的生成器和枚举器:http://www.codeproject.com/Articles/155462/IEnumerable-Lazy-and-Dangerous
更新: 实际上,当您使用IEnumerable与引用类型时,您可以获得与以前相同的对象。请阅读以下答案:https://stackoverflow.com/a/14361094/1467309
答案 1 :(得分:0)
Text
的属性TextBox
获取DependencyProperty
Text
的值,这只能通过UI线程完成。您正在从工作线程访问textBoxCodiceArticolo.Text
。