BackgroundWorker和剪贴板

时间:2013-04-09 21:53:40

标签: c# wpf backgroundworker clipboard

我发疯了一个简单的代码,我使用BackgroundWorker来自动执行基本操作。我应该将内容添加到剪贴板吗。

在BackgroundWorker的方法中执行此代码后:

Clipboard.SetText (splitpermutation [i]);

我得到一个错误,说明线程必须是STA,但我不明白该怎么做。 这里有更多代码:(不是全部)

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

3 个答案:

答案 0 :(得分:6)

您可以将其封送到UI线程以使其正常工作:

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

答案 1 :(得分:3)

BackgroundWorker在.NET线程池上运行。线程池线程在COM多线程单元中运行。要使用剪贴板,您必须在单线程单元中运行。您可以创建自己的线程并将其设置为在STA中运行,但最好使用Control.Invoke(或BeginInvoke)来返回用户界面线程(必须是STA线程)。

答案 2 :(得分:0)

你得到的例外是因为你试图在UI线程之外的UI线程上做一些事情(顾名思义,BackgroundWorker在后​​台做了一些事情,为此它需要创建一个单独的线程。)

虽然Reed发布的答案(即使用Dispatcher.BeginInvoke)是避免此异常的一种方法,但我想知道为什么要尝试从主要工作方法向剪贴板发送内容。第一名......

BackgroundWorker会公开ProgressChanged(您可以定期从您的工作方法调用)或RunWorkerCompleted(当主要工作方法完成时会触发)等事件。

在这些事件中使用Clipboard.SetText不应该导致您看到的异常,这似乎是在使用BackgroundWorker时在UI线程上执行操作的首选方式。< / p>