デバイスをポーリングするために、SharpSNMP (8.5、NuGet の最新バージョン) を非同期で使用しています。それは非常に簡単で、問題なく動作しているように見えますが、SharpSnmpLib のソース コードを見ても理解できないことが 1 つあります。それは、コールバック メソッドに提供されるオブジェクトの型が指定されている場所です。
例えば:
ここでは、新しいSNMP GETリクエストを作成し、 BeginGetResponseを呼び出します。
var message = new GetRequestMessage(RequestCounter.NextId, VersionCode.V2, community, oids);
var udpSocket = SNMPAddress.GetSocket();
// pass my GetRequestMessage as the state object
var v = message.BeginGetResponse(SNMPAddress, new UserRegistry(), udpSocket, new AsyncCallback(HandlePollCompletion), message);
メソッドmessage.BeginGetResponseはSnmpMessageExtensionクラスで定義され、最終的にソケットでBeginReceiveを呼び出します (次のスニペットはSharpSNMP コードからのものです)。
public static IAsyncResult BeginGetResponse(this ISnmpMessage request, IPEndPoint receiver, UserRegistry registry, Socket udpSocket, AsyncCallback callback, object state)
{
// ** code snipped from example for readability **
var ar = udpSocket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, callback, state);
return new SnmpMessageAsyncResult(ar, udpSocket, registry, receiver, buffer);
}
これはSnmpMessageAsyncResultオブジェクトを返しますが、これがudpSocket.BeginReceiveの呼び出しに渡されることはないため、後でコールバック メソッドに渡される方法がわかりません。
返信が来ると、ハンドラー メソッドのHandlePollCompletionが呼び出されます。
private void HandlePollCompletion(IAsyncResult ar)
{
// grab handle to original message
GetRequestMessage message = (GetRequestMessage)ar.AsyncState;
// end the async call
try
{
var response = message.EndGetResponse(ar);
}
catch (Exception ex) {}
// process reply here
}
ブレークポイントを設定すると、 HandlePollCompletion(IAsyncResult ar)に渡されるオブジェクトarの型がSnmpMessageAsyncResultであることがわかります。
しかし、私が見る限り、HandlePollResult(IAsyncResult ar)はソケットによって呼び出されます。つまり、SharpSNMP 内からではありません。
では、オブジェクトがHandlePollCompletion(IAsyncResult ar)にSnmpMessageAsyncResultに渡されるメカニズムは何ですか? おそらく、私は思ったほど非同期モデルを理解していません..
あなたの洞察に感謝します、ジャイルズ。