我只是将 GUI 应用程序从 更改为STAThread
,MTAThread
因为它执行一些并行后台工作。现在我遇到了从MTAThread
应用程序中访问剪贴板的问题。
我尝试自己创建一个专用的 STA 线程,失败了,然后尝试了这个类https://stackoverflow.com/a/21684059/2477582并再次失败。
从 dot net framework source code我发现Application.OleRequired()
不匹配ApartmentState.STA
是 raise 的唯一条件ThreadStateException
。但这与我的实现相匹配,尽管引发了异常!
没有 VS 调试器的测试让我从这个“.NET 遇到未处理的异常”对话框继续应用程序,然后剪贴板包含正确的值!所以它有效,但我没有机会捕捉到异常,因为它从一些无法识别的线程 void 直接引发到Application.Run(new MyMainform())
.
我做错了什么还是 .NET 行为在这里改变了?
程序.cs:
[MTAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new ds_Main());
}
catch (System.Threading.ThreadStateException ex)
{
// It always falls out here
System.Diagnostics.Debug.WriteLine("ThreadStateException: " + ex.ToString());
}
}
ds_Main.cs,DataGridView KeyDown 处理程序:
private void ds_ImportTableView_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.C)
{
string ll_CopyString = "foobar"; // some other stuff is here of course...
try
{
Thread l_StaThread = new Thread(() =>
{
// this prints: STA=?STA
System.Diagnostics.Debug.WriteLine(Application.OleRequired().ToString() + "=?" + System.Threading.ApartmentState.STA.ToString());
try
{
Clipboard.SetDataObject(ll_CopyString);
}
catch (Exception ex)
{
// It never catches here ...
System.Diagnostics.Debug.WriteLine("Exception in STA Delegate: " + ex.Message);
}
});
l_StaThread.SetApartmentState(ApartmentState.STA);
l_StaThread.Start();
}
catch (Exception ex)
{
// It doesn't catch here either ...
System.Diagnostics.Debug.WriteLine("Exception in STA Thread: " + ex.ToString());
}
}
}