4

COMコンポーネントを使用するC#アプリケーションがあります。このCOMコンポーネントは、その処理を行うためにメッセージポンプ(Application.Run())を必要とします。これは、メインスレッドでスタックしていることを意味します。しかし、最近、別のApplication.Runを、独自のApplicationContextを取得する別のスレッドで開始できることを発見しました。

そのため、COMコンポーネントを独自のApplication.Run()内の独自のスレッドでホストしたいのですが、UIフォームを作成せずに、新しいスレッドで作業を開始する方法を理解できません。

スレッドと通信する必要があるWindowsFormsSynchronizationContextは、Application.Run()まで作成されません。しかし、Application.Run()が呼び出されると、SynchronizationContextを取得する方法がわかりません。そのスレッドで単一のイベントを発生させることができれば、それを使用して全体をブートストラップすることができます(COMオブジェクトの作成など)が、フォームなしで新しいイベントループにフックする場所はないようです。 。

メッセージフィルターのインストール(新しいスレッドでメッセージが発生しない)、実行コンテキストを別のスレッドにコピーし、そこからSynchronizationContextを取得しようとする(のExecutionContextのコピーを拒否する)など、あらゆる種類の複雑なことを試しました。すでにスレッドを実行している)、Application.Run()を開始する前にThread.CurrentContextを取得し、DoCallbBack()を呼び出す(DoCallbackは元のスレッドで終了します)など。私が試したことは何も機能しません。

4

1 に答える 1

7

ブライス、

Anders Hejlsbergの「TheFutureofC#」に関する講演からこのスニペットを適応させることができるかもしれません。 これは、スレッドにメッセージポンプを追加して、REPLループを使用してウィンドウを開くことができるようにする小さなクラスであり、メッセージポンプが接続されます。

コードは次のようになります。

using System.Windows.Forms;
using System.Threading;
class UserInterfaceThread()
{
    static Form window;

    public UserInterfaceThread() 
    {
        var thread = new Thread(() => {
            window = new Form();
            var handle = window.Handle;
            Application.Run();
            });
        thread.Start();
    }
    public void Run(Action action)
    {
        window.Invoke(action);
    }
}

このコードに関連する議論は、レビューしたい場合は、アンダースの話の1時間5分後に行われます。

于 2009-09-15T16:43:24.037 に答える