いくつかの並列バックグラウンド作業を行うため、GUI アプリケーションを からSTAThread
に変更しています。ここで、アプリケーションMTAThread
内からクリップボードにアクセスする際に問題が発生しました。MTAThread
専用の STA スレッドを自分で作成しようとしましたが失敗し、このクラスhttps://stackoverflow.com/a/21684059/2477582を試してみましたが、再び失敗しました。
ドット ネット フレームワークのソース コードから 、Application.OleRequired()
一致しないApartmentState.STA
ことが発生する唯一の条件であることがわかりましたThreadStateException
。しかし、これは私の実装に一致しますが、それでも例外が発生します!
VS デバッガーを使用しないテストでは、この ".NET で未処理の例外が発生しました" ダイアログからアプリケーションを続行でき、クリップボードに正しい値が含まれています。したがって、動作しますが、識別できないスレッド void から直接 に発生するため、例外をキャッチする機会がありませんApplication.Run(new MyMainform())
。
何か間違っているのでしょうか、それとも .NET の動作がここで変更されたのでしょうか?
Program.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());
}
}
}