2013-04-09 18 views
5

Sto impazzendo con un semplice codice [WPF C#] in cui utilizzo un BackgroundWorker per automatizzare le operazioni di base. Dovrei aggiungere un contenuto negli appunti.BackgroundWorker e ClipBoard

Dopo l'esecuzione di questo codice nel metodo della BackgroundWorker:

Clipboard.SetText (splitpermutation [i]); 

ottengo un errore che spiega il filo deve essere STA, ma non capisco come fare. Qui più codice: (non tutti)

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]); 
         [...] 
        } 
} 

risposta

4

Si potrebbe schierare questo al thread UI per farlo funzionare:

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

Dov'è il Dispatcher? Cos'è questo'? Non riesco a trovarlo. – codemann8

+0

@ codemann8 In WPF, ogni elemento dell'interfaccia utente ha un Dispatcher - questo era in codice dietro –

+0

Non ho alcuna esperienza in WPF, sto usando un progetto C# WinForms standard ... Esiste una soluzione equivalente lì? – codemann8

1

Le BackgroundWorker viene eseguito sul pool di thread .NET. I thread del pool di thread vengono eseguiti nell'appartamento multi-thread COM. Per utilizzare gli Appunti, è necessario essere in esecuzione in un appartamento a thread singolo. È possibile creare il proprio thread e impostarlo per l'esecuzione in uno STA, ma probabilmente sarebbe meglio utilizzare Control.Invoke (o BeginInvoke) per tornare su un thread dell'interfaccia utente (che deve essere un thread STA).

0

L'eccezione che si ottiene è perché si sta tentando di fare qualcosa sul thread dell'interfaccia utente dall'esterno del thread dell'interfaccia utente (a BackgroundWorker, come suggerisce il nome, fa qualcosa in background, e per questo deve creare un thread separato).

Mentre la risposta inviata da Reed (ovvero utilizzando Dispatcher.BeginInvoke) è un modo per evitare questa eccezione, mi chiedo PERCHÉ si sta tentando di inviare qualcosa negli appunti dal metodo di lavoro principale in primo luogo ...

il BackgroundWorker espone eventi come ProgressChanged (che è possibile chiamare periodicamente dal vostro metodo di lavoro) o RunWorkerCompleted (che scatterà quando il metodo di lavoro principale termina).

L'utilizzo di Clipboard.SetText in uno di questi eventi non dovrebbe causare l'eccezione che si sta vedendo, e questo sembra essere il modo preferibile di fare le cose sul thread dell'interfaccia utente quando si lavora con lo BackgroundWorker.

Problemi correlati