我发疯了一个简单的代码,我使用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]);
[...]
}
}
答案 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>