2

保留中の操作がある場合、たとえば

stream.BeginRead(_buffer, 0, _buffer.Length, _asyncCallbackRead, this);

ストリームプロバイダーを閉じます。

serialPort.Close();

当然のことながら、例外が発生します。

ポートを閉じる前に、保留中の APM 操作をキャンセルするための推奨される方法はありますか?


Colby の返答は、私が望んでいたものではありませんが、少なくとも無駄な調査の道を閉ざしてくれます。

幸いなことに、私は解決策を見つけました。

ストリームごとに、さまざまな状態情報を class に保持しDeviceSessionます。このクラスには、着信データを処理するReadStreamの実装を提供するメソッドがあります。AsyncCallback

_asyncCallbackReadアンダースコアで始まる他のすべての変数は、DeviceSession のコンストラクターで割り当てられたクラスのプライベート メンバーであることに注意してください。

コンストラクターは、 への最初の呼び出しも提供します_stream.BeginRead

void ReadStream(IAsyncResult ar)
{
  if (IsOpen) 
    try
    {
      DevicePacket packet;
      int cbRead = _stream.EndRead(ar);
      _endOfValidData += cbRead;
      while ((packet = GetPacket()) != null)
        CommandStrategy.Process(this, packet);
      _stream.BeginRead(_buffer, _endOfValidData, 
        _buffer.Length - _endOfValidData, 
        _asyncCallbackRead, null);
    }
    catch (Exception ex)
    {
      Trace.TraceError("{0}\r\n{1}", ex.Message, ex.StackTrace);
      _restart(_streamProvider, _deviceId);
    }
}

わざわざ設定していないことに注意してくださいar.AsyncState。コールバック デリゲートは DeviceSession の特定のインスタンスのメソッドを参照するため、厳密に型指定された詳細なコンテキスト情報 (DeviceSession のこのインスタンスのメンバーに含まれる) は自動的にスコープに含まれます。これが、セッション オブジェクトを持つポイントです。

リスナーの中止に戻ると、ストリーム プロバイダーを閉じるとコールバックがトリガーされますが、EndRead を呼び出そうとするとIOException.

通常、このような例外は、リスナーの再起動が必要な障害を示しており、ストリーム プロバイダーを再起動してセッションを再作成することで対応する必要があります。これは、プロバイダーに障害が発生したか、ユーザーが接続を再開しようとしているか (たとえば、新しいデバイスをポートに接続したか) を判断する信頼できるストリーム プロバイダーに依存しない方法がないため、複雑です。

IsOpen秘訣は、さらにコンテキスト ( ) をに追加しDeviceSessionて、セッションが開いているか閉じているかを示し、それを使用して の最終的な中止実行をスムーズに完了することですReadStream

の場合IsOpentrueIOException回復が必要な障害を表します。IsOpen障害がfalse意図的に引き起こされたものであり、アクションは不要な場合。

4

2 に答える 2

2

[C# を介した Richter の CLR の APM に関する章に触発されて、私は SO がこの件に関してどんな利点を持っているかを見ることにし、この質問を見つけました。ピーターはここで素晴らしい質問をしたと思い、少し調査を行いました-これが結果です]

C# による CLR の Jeffrey Richter (第 27 章) は、(おそらく) APM のプログラミングから多くの苦痛を取り除いてくれる彼の AsyncEnumerator クラスについて説明しています。このクラス (彼が無料で入手できるPower Threading Libraryの一部) の機能の 1 つは、非同期操作をキャンセルする機能です。

クラスは上記のリンクからダウンロードできます。このページには、lib の限定的なサポートを提供するためにセットアップされた Yahoo Group Richter へのリンクも含まれています。

彼は、次の MSDN 記事でライブラリを紹介しています。

AsyncEnumerator による簡素化された APM AsyncEnumerator の
その他の機能

于 2010-10-06T05:39:33.720 に答える
0

これは、フレームワークでは直接サポートされていません。最善の策は、スレッドを生成するラッパーを作成し、イベントなどの同期プリミティブを使用してキャンセル要求を通知することです。

HTH

コルビー・アフリカ

于 2008-12-22T02:54:01.560 に答える