调用线程无法访问此对象

问题描述:

此代码“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 )}

+0

为什么你评论了大部分'doStg'? – ChaosPandion 2010-11-19 16:27:37

+0

@Chaos:因为它不相关。 – 2010-11-19 16:30:37

+0

什么是完整的例外?另外,你注释掉的那些实际上迭代了linq查询的位是什么样的? – 2010-11-19 16:32:11

移动下面的代码行:

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; 
    } 
+0

我的WPF有点弱。你是否说非UI元素受到跨线程操作的保护? – ChaosPandion 2010-11-19 16:37:07

+0

@Chaos:问题是,在原始代码中,'DataContext'运行在一个单独的线程上。这是造成这种情况的'BackgroundWorker',而不是WPF。我不确定底层机制是什么,但我几乎肯定将'DataContext'放在与Linq查询相同的线程上可以解决问题。 – 2010-11-19 16:38:33

+0

@Chaos:如果您的DataClassesDataContext继承自DispatcherObject(如果它是一个DependencyObject),它将具有线程关联。由于我们不知道这个类是什么样子,这是一个很好的假设。 – 2010-11-19 16:51:34