2013-04-09 12 views
5

Ich bin verrückt mit einem einfachen Code [WPF C#], in dem ich einen BackgroundWorker verwende, um die Grundoperationen zu automatisieren. Soll ich einen Inhalt zur Zwischenablage hinzufügen?BackgroundWorker und ClipBoard

Nach diesen Code in das Verfahren der Ausführung Background:

Clipboard.SetText (splitpermutation [i]); 

bekomme ich einen Fehler, der den Thread erklärt STA sein muss, aber ich verstehe nicht, wie zu tun ist. hier mehr Code: (nicht alle)

private readonly BackgroundWorker worker = new BackgroundWorker(); 

private void btnAvvia_Click(object sender, RoutedEventArgs e) 
{ 
      count = lstview.Items.Count; 
      startY = Convert.ToInt32(txtY.Text); 
      startX = Convert.ToInt32(txtX.Text); 
      finalY = Convert.ToInt32(txtFinalPositionY.Text); 
      finalX = Convert.ToInt32(txtFinalPositionX.Text); 
      incremento = Convert.ToInt32(txtIncremento.Text); 
      pausa = Convert.ToInt32(txtPausa.Text); 

      worker.WorkerSupportsCancellation = true; 
      worker.RunWorkerAsync(); 

      ... 
} 

private void WorkFunction(object sender, DoWorkEventArgs e) 
{ 
    [...] 
        if (worker.CancellationPending) 
        { 
         e.Cancel = true; 
         break; 
        } 
        else 
        { 
         [...] 
         Clipboard.SetText(splitpermutation[i]); 
         [...] 
        } 
} 

Antwort

4

du auf dem UI-Thread Marschall könnte, damit es funktioniert:

else 
{ 
    [...] 
    this.Dispatcher.BeginInvoke(new Action(() => Clipboard.SetText(splitpermutation[i]))); 
    [...] 
} 
+0

Wo ist Dispatcher? Was ist das'? Ich kann es nicht finden. – codemann8

+0

@ codemann8 In WPF hat jedes UI-Element einen Dispatcher - das war in Code hinter –

+0

Ich habe keine Erfahrung in WPF, ich benutze ein Standard WinForms C# -Projekt ... Gibt es dort eine äquivalente Lösung? – codemann8

1

Die BackgroundWorker läuft auf dem .NET-Thread-Pool. Threadpool-Threads werden in dem COM-Multithread-Apartment ausgeführt. Um die Zwischenablage zu verwenden, müssen Sie in einem Singlethread-Apartment ausgeführt werden. Sie könnten Ihren eigenen Thread erstellen und ihn so einrichten, dass er in einer STA ausgeführt wird, aber es wäre wahrscheinlich am besten, Control.Invoke (oder BeginInvoke) zu verwenden, um auf einen Benutzerschnittstellen-Thread (der ein STA-Thread sein muss) zurückzugreifen.

0

Die Ausnahme, die Sie erhalten, ist, weil Sie versuchen, etwas auf dem UIhread außerhalb des UI-Threads zu tun (eine BackgroundWorker, wie der Name schon sagt, tut etwas im Hintergrund, und dafür muss es erstellen ein separater Thread).

Während die Antwort, die von Reed (also Dispatcher.BeginInvoke) geschrieben wird, eine Möglichkeit ist, diese Ausnahme zu vermeiden, frage ich mich, warum Sie versuchen, etwas von der Hauptarbeitsmethode an die Zwischenablage zu senden ...

die BackgroundWorker macht Veranstaltungen wie ProgressChanged (die Sie in regelmäßigen Abständen von der Arbeit Methode aufrufen können) oder RunWorkerCompleted (das Feuer wird, wenn die Hauptarbeitsmethode beendet).

Die Verwendung von Clipboard.SetText in einem dieser Ereignisse sollte nicht die Ausnahme verursachen, die Sie sehen, und dies scheint die bevorzugte Vorgehensweise im UI-Thread bei der Arbeit mit BackgroundWorker zu sein.