调用线程无法访问此对象
此代码“var results ..”抛出异常“调用线程无法访问此对象,因为不同的线程拥有它”。 LINQ查询不错。调用线程无法访问此对象
请问我做错了什么?
DataClassesDataContext db = new DataClassesDataContext();
bool doStg()
{
try
{
var results = from t in db.table
select t;
//doing some things..
return true;
}
catch (Exception Exception)
{
MessageBox.Show(Exception.Message);
return false;
}
}
bool stepByStep()
{
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 1"), null);
if (!doStg()) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 33), null);
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 2"), null);
if (!doStg()) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 66), null);
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 3"), null);
if (!doStg()) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 100), null);
return true;
}
private void button_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
args.Result = stepByStep();
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
object result = args.Result;
if ((bool)result) { MessageBox.Show("Done"); }
else { MessageBox.Show("Processing stopped."); }
};
worker.RunWorkerAsync();
}
编辑:
异常源: “将System.Data.Linq”
TargetSite:{System.Data.Linq.SqlClient.SqlNode VisitInvocation(System.Linq.Expressions.InvocationExpression )}
移动下面的代码行:
DataClassesDataContext db = new DataClassesDataContext();
放入您的stepByStep()
方法体中,然后将db
作为参数传递给您的doStg()
方法。
bool doStg(DataClassesDataContext db)
{
try
{
var results = from t in db.table
select t;
//doing some things..
return true;
}
catch (Exception Exception)
{
MessageBox.Show(Exception.Message);
return false;
}
}
bool stepByStep()
{
DataClassesDataContext db = new DataClassesDataContext();
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 1"), null);
if (!doStg(db)) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 33), null);
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 2"), null);
if (!doStg(db)) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 66), null);
Dispatcher.BeginInvoke(new Action(() => info.Text = "Step 3"), null);
if (!doStg(db)) { return false; }
Dispatcher.BeginInvoke(new Action(() => progressBar.Value = 100), null);
return true;
}
我的WPF有点弱。你是否说非UI元素受到跨线程操作的保护? – ChaosPandion 2010-11-19 16:37:07
@Chaos:问题是,在原始代码中,'DataContext'运行在一个单独的线程上。这是造成这种情况的'BackgroundWorker',而不是WPF。我不确定底层机制是什么,但我几乎肯定将'DataContext'放在与Linq查询相同的线程上可以解决问题。 – 2010-11-19 16:38:33
@Chaos:如果您的DataClassesDataContext继承自DispatcherObject(如果它是一个DependencyObject),它将具有线程关联。由于我们不知道这个类是什么样子,这是一个很好的假设。 – 2010-11-19 16:51:34
为什么你评论了大部分'doStg'? – ChaosPandion 2010-11-19 16:27:37
@Chaos:因为它不相关。 – 2010-11-19 16:30:37
什么是完整的例外?另外,你注释掉的那些实际上迭代了linq查询的位是什么样的? – 2010-11-19 16:32:11