2010-11-19 1 views
0

Dieser Code "var results .." wirft Ausnahme "Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da ein anderer Thread es besitzt". Die LINQ-Abfrage ist nicht schlecht.Der aufrufende Thread kann nicht auf dieses Objekt zugreifen

Bitte was mache ich falsch?

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(); 
    } 

EDIT:

Quelle der Ausnahme: "System.Data.Linq"

Target: {System.Data.Linq.SqlClient.SqlNode VisitInvocation (System.Linq.Expressions.InvocationExpression)}

+0

Warum haben Sie die Mehrheit von 'doStg' auskommentiert? – ChaosPandion

+0

@Chaos: Weil es nicht relevant ist. –

+0

Was ist die vollständige Ausnahme? Auch die Bits, die Sie auskommentiert haben, die tatsächlich über die linq-Abfrage iterieren, wie sieht das aus? –

Antwort

1

die folgende Codezeile verschieben:

DataClassesDataContext db = new DataClassesDataContext(); 

in Ihren stepByStep() Methodenkörper und übergeben Sie dann db als Parameter an Ihre doStg() Methode.

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

Mein WPF ist ein bisschen schwach. Wollen Sie sagen, dass Nicht-ui-Elemente vor Cross-Thread-Manipulation geschützt sind? – ChaosPandion

+0

@Chaos: Das Problem ist, dass der 'DataContext' im ursprünglichen Code in einem separaten Thread läuft. Es ist der 'BackgroundWorker', der dies verursacht, nicht WPF. Ich bin mir nicht sicher, was der zugrundeliegende Mechanismus ist, aber ich bin fast sicher, dass das Setzen des 'DataContext' im selben Thread wie die Linq-Abfrage das Problem lösen wird. –

+0

@Chaos: Wenn Ihr DataClassesDataContext von DispatcherObject erbt (wenn es beispielsweise ein DependencyObject ist), hat es eine Thread-Affinität. Da wir nicht wissen, wie diese Klasse aussieht, ist das eine gute Annahme. –