我的WinForms应用程序中有一个ThreadStateException。
重现步骤:
在点击事件中,请执行:
timer1.Interval = 1000;
timer1.Tick += timer1_Tick;
timer1.Start();
与
void timer1_Tick(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate
{
StringCollection paths =
new StringCollection { @"c:\my.txt", @"c:\my.png" };
Clipboard.SetFileDropList(paths);
});
}
例外告诉我:
在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式。确保您的Main函数标记了STAThreadAttribute。
但主要已经有[STAThread]属性。
如何解决?
答案 0 :(得分:2)
Thread.SetApartmentState()方法在这里很重要。剪贴板是一个COM对象,它不是线程安全的。有许多Windows功能,其行为与此类似,Drag + Drop和OpenFileDialog等shell对话框是其他示例。
你不能设置线程池线程的公寓状态,它总是MTA(多线程公寓)。您可以在常规线程上,但是额外的STA要求是您还要泵送消息循环(Application.Run)。这给了你完全相同的问题:你不能阻止或花很长时间来执行代码。
简单的解决方案是在线程上执行任何需要很长时间才能执行的操作。并从UI线程进行剪贴板调用。使用Control.BeginInvoke()或更好的BackgroundWorker.RunWorkerCompleted。