1

.NET アプリケーションで、サードパーティの ActiveX コントロールを使用してデバイスに接続しています。このコンポーネントには UI がないため、Windows アプリ、コンソール アプリ、または Windows サービスから使用できます。問題は、アプリケーションの種類によって動作が異なることです。

コンソール アプリケーション (または Windows サービス) からの使用:

  1. ThreadPool を使用してコンポーネント メソッドを呼び出します。つまり、メイン スレッド以外のスレッドで呼び出します。
  2. メソッドは同じスレッドで実行されます。(予想通り)
  3. メソッドのコールバックは同じスレッドで実行されています。(予想通り)

ただし、Windows アプリケーションから使用する場合:

  1. つまり、UI スレッド以外のスレッドで、ThreadPool を使用してコンポーネント メソッドを呼び出します。--> この時点で、ActiveX コントロールは UI スレッドに変更されたようです。
  2. メソッドは UI スレッドで実行されます (UI のブロックが表示されます!)
  3. メソッド コールバックは UI スレッドで実行されています。

UI以外のスレッドで呼び出しが実行されるように、コンポーネントを分離する方法はありますか?

ありがとう!

4

1 に答える 1

1

長い検索と読書の後、私はそれを機能させることができました。これが私が使用したコードで、いくつかのコメントがあります。詳細については、Google で「.net Com thread sta」などを検索してください。

// COM objects will always execute in the same thread where they were created, 
// so it's better to create them in another thread (that must be alive as long as the object
// exists) to avoid blocking the UI thread.
var thread = new Thread(CreateComponent);
thread.SetApartmentState(ApartmentState.STA);
threads.Add(thread);

thread.Start("optional parameters");


private void CreateComponent(object obj)
{
    var parameters = obj as string;

    // Create the COM object here
    var component = new CreateYourCOMComponent(parameters);

    // You might want to catch all unhandled exceptions too
    Application.ThreadException += Application_ThreadException;

    // Once the object is created, the thread must be alive during 
    // the whole time the COM object remains alive. The Application.Run 
    // will pump the messages required for COM and prevent the thread for exiting.
    Application.Run();
}
于 2013-01-15T17:35:33.440 に答える