2010-11-19 62 views
0

此代碼「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

回答

1

移動下面的代碼行:

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