3

機器メーカーが提供する .Net ライブラリに接続できる商用機器がいくつかあります。そのため、ライブラリや機器を制御することはできず、自分のコードのみを制御できます。

メーカーは、ライブラリ経由で機器に接続していない場合でも問題なく動作するようにシステムをセットアップしています。ただし、彼らのライブラリに接続する場合は、機器の実行速度によって設定された速度で Windows メッセージ ポンプを処理するという暗黙の要件があります。これは、彼らのライブラリが機器の動作を追跡するサブスクライブできるイベント システムを実装しているためですが、アプリケーション コードが WinForms ベースであることを前提としています。(しかし、彼らのドキュメントにはこれを明示的に述べているものは何もありません.2つの.NetサンプルプログラムはすべてWinFormsベースです.)私は彼らの技術サポートに、WinFormsアプリケーションを使用することを期待していることを確認しました.

私の場合、C# の非 WinForms ベースのアプリケーション (実際には Windows サービスであるため、UI スレッドはありません) を作成しており、機器に接続しているにもかかわらず、どのイベントにもサブスクライブしていません。その結果、サブスクライブしていないすべてのイベントを処理するには、WinForms アセンブリを参照し、Application.DoEvents() を十分な速度で呼び出す必要があることがわかりました。

だから私の質問はこれらです:

  1. この場合、私の唯一のオプションは Application.DoEvents() を呼び出すことですか?
  2. または、これを行うより現代的な方法はありますか?
  3. 20mS レートで DoEvents() を呼び出すと、どのような影響がありますか?
  4. 関係ありませんが、WPF ベースのアプリケーションを作成した場合、そのプログラムはメッセージ ポンプにサービスを提供する可能性がありますか?

編集

機器に接続し、Windows メッセージ ポンプにサービスを提供しない場合 (イベントのいずれにもサブスクライブしていなくても)、機器が予期せぬ動作を開始することを付け加えておきます。

編集 2

また、ライブラリとのインターフェイスに使用するスレッドは、最初の Windows サービス スレッドから約 2 世代または 3 世代分削除されています。

4

2 に答える 2

6

これは問題ありません。UI がないため、DoEvents の通常の警告はここでは適用されません。影響はなく、率は現実的です。Application.Run() もメッセージ ループをポンピングしますが、呼び出しが返されないため、スレッドの制御が難しくなります。はい、WPF もメッセージ ループをポンピングしますが、UI がないため、これを使用する意味はほとんどありません。

SetApartmentState() を呼び出して STA を選択し、サービス スレッドを初期化する必要があります。これにより、COM サーバーが正常に動作することが保証されます。

ああ、頭に浮かぶ 1 つの警告: スレッドが 100% コアを燃やさないようにするために何かをする必要があります。Application.Run() では自動ですが、「ゲーム ループ」の DoEvents では自動ではありません。20ミリ秒のレートを指定できるので、すでに行っていると思います。それ以外の場合は、サービス停止要求イベントで WaitHandle.WaitOne(20) を呼び出すのが一般的な方法です。

于 2010-10-01T13:24:24.607 に答える
2

スレッド上でApplicationContextApplication.Run()を受け取るか、パラメーターを使用しないバージョンを呼び出すだけで、フォームのないメッセージ ポンプを使用できます。

編集: サービスの中でApplicationContext.ExitThread()を呼び出すことができるように、 ApplicaitonContext バージョンをお勧めしOnStop()ます。

于 2010-10-01T13:20:56.870 に答える