わかりました、これは私の最初のスタック オーバーフローの質問です。質問のより良い方法や、次回は何を含める必要があるかをお気軽に提案してください。ほとんどの場合、Google で答えを得ることができますが、これは少しトリッキーです...
UDP ポートをリッスンし、着信 UDP メッセージを処理する Windows アプリケーションを C# で作成しています。より具体的には、UDPClient
クラスを使用し、BeginReceive メソッドを使用してリッスンしています。受信コールバックは、独自のメッセージ受信イベントを発生させ、UDP クライアントを再度リセットします。この「MessageReceived」イベントは、その後、プロセッサ オブジェクトによって処理されます。
私のマネージャーが私に次のような質問をするまで、それはすべてかなり賢いと思いました:
- これは一度に何通のメッセージを受信できますか? それ以上になるとどうなりますか?
- メッセージはキューに入れられていますか、それとも処理に時間がかかりすぎると失われますか?
- 処理に時間がかかりすぎるとどうなりますか?
最後のメッセージがまだ処理中であるため、メッセージを失うことはありません。また、メモリ不足のため、システムがクラッシュするまでメッセージを構築することもできません。彼が聞きたいのは (そして当然のことながら)、メッセージの「嵐」を処理する決定論的な方法があるというある種の検証です。残念ながら、答えを得るためにこれをどこに行けばよいかわかりません。関連するコードと思われるものを以下に含めました。
そう:
- 上記の質問に対する答えを知っている人はいますか?
- これらの答えや、この種のことに従うべきいくつかのパターンを見つけるために、どこで調査を行いますか?
- デバッグ/パフォーマンス プロファイリングの処理を監視するには、どのようなツールを使用できますか?
設計で大きな間違いを犯した場合、それを解決するにはどうすればよいですか (つまり、キューを導入する、スレッド プールを使用するなど)。
public void ReceiveCallback(IAsyncResult ar) { //Cast the item back to the listener UdpListener listener = (UdpListener)ar.AsyncState; //If we are supposed to be listening, then get the data from the socket //Listen is false during shutdown if (Listen) { //The try catch is placed inside the listen loop so that if there is an error in the processing it will //recover and listen again. this may cause more exceptions but we can be sure that it will not // stop listening without us knowing try { //Address and port from the external system IPEndPoint ep = listener.EndPoint; //Get the data from the async read Byte[] receiveBytes = listener.Client.EndReceive(ar, ref ep); //Reset the socket to listen again listener.Client.BeginReceive(new AsyncCallback(ReceiveCallback), listener); //Execute the event to pass external components the message HeartbeatEventArgs hea = new HeartbeatEventArgs(DateTime.Now, ep, receiveBytes); OnHeartbeatReceived(hea); //Ack back to the external system HeartbeatAcknowledgement(new IPEndPoint(ep.Address, ep.Port), receiveBytes); } catch (Exception e) { log.Error(e.Message); //Reset the socket to listen again } } }
listner は単なるラッパーUDPClient
です。次のように:
#region UdpClient Wrapper (UdpListener)
/// <summary>
/// UdpListener is used to control the asynchronous processing of a UDPClient object.
/// </summary>
public class UdpListener
{
/// <summary>
/// IPEndpoint on which to accept a connection. Usually set to "Any".
/// </summary>
public IPEndPoint EndPoint { get; set; }
/// <summary>
/// The socket based client object that is used for communication
/// </summary>
public UdpClient Client { get; set; }
public UdpListener(int port)
{
EndPoint = new IPEndPoint(IPAddress.Any, port);
Client = new UdpClient(EndPoint);
}
}
#endregion
ありがとう、
ディンズデール