Ich möchte das tun
%Vor% Aber anstatt UdpClient.Receive
zu verwenden, muss ich UdpClient.BeginReceive
verwenden. Das Problem ist, wie mache ich das? Es gibt nicht viele Beispiele, die BeginReceive
verwenden, und das MSDN-Beispiel hilft überhaupt nicht. Soll ich BeginReceive
verwenden oder einfach unter einem separaten Thread erstellen?
Ich erhalte immer ObjectDisposedException
Ausnahme. Ich bekomme nur die ersten Daten gesendet. Die nächsten Daten werden eine Ausnahme auslösen.
Was gibt's?
Übrigens ist die allgemeine Idee:
Es scheint, dass UdpClient.BeginReceive()
und UdpClient.EndReceive()
nicht gut umgesetzt sind. Und sicherlich verglichen mit der Implementierung des TcpListeners, ist es viel schwieriger zu verwenden.
Es gibt mehrere Dinge, die Sie tun können, um mit UdpClient.Receive()
besser für Sie zu arbeiten. Erstens ermöglicht das Setzen von Timeouts auf dem zugrunde liegenden Socket-Client, dass die Steuerung durchläuft (zu einer Ausnahme), wodurch der Steuerungsfluss fortgesetzt oder beliebig geloopt werden kann. Zweitens können Sie durch das Erstellen des UDP-Listeners für einen neuen Thread (dessen Erstellung ich nicht gezeigt habe) den Semi-Blocking-Effekt der UdpClient.Receive()
-Funktion vermeiden, und Sie können den Thread später effektiv abbrechen, wenn Sie dies richtig tun .
Der folgende Code besteht aus drei Teilen. Der erste und der letzte Teil sollten sich in der Hauptschleife an den Ein- und Ausstiegspunkten befinden. Der zweite Teil sollte in dem neuen Thread sein, den Sie erstellt haben.
Ein einfaches Beispiel:
%Vor% Außerdem können Sie UdpClient.Available > 0
überprüfen, um festzustellen, ob UDP-Anforderungen vor der Ausführung von UdpClient.Receive()
in die Warteschlange gestellt wurden. Dadurch wird der Blockierungsaspekt vollständig entfernt. Ich schlage vor, dass Sie dies mit Vorsicht versuchen, da dieses Verhalten nicht in der Microsoft-Dokumentation angezeigt wird, aber scheint zu funktionieren.
Hinweis:
Der MSDN-Exmaplcode Sie haben möglicherweise gefunden, während die Erforschung dieses Problems eine zusätzliche benutzerdefinierte Klasse
Die Zeitüberschreitungen müssen nicht unbedingt Sie können festlegen, dass Ihre App vollständig beendet wird. Sie können jedoch andere Aktionen in dieser Schleife ausführen, anstatt sie für immer zu blockieren.
Der Befehl listener.Close () ist wichtig, da er den UdpClient dazu zwingt Wirf eine Ausnahme und beende die Schleife, damit Thread.Abort () behandelt werden kann. Ohne diese Option können Sie den Listener-Thread möglicherweise nicht ordnungsgemäß beenden, bis das Zeitlimit überschritten wird oder ein UDP-Paket empfangen wird, das dazu führt, dass der Code über den UdpClient.Receive () - Block hinaus fortgesetzt wird.
Nur um diese unbezahlbare Antwort hinzuzufügen, hier ist ein funktionierendes und getestetes Codefragment. (Hier in einem Unity3D-Kontext, aber natürlich für jedes c #.)
%Vor%schauen Sie zuerst auf MSDN. Sie bieten ein gutes Beispiel. Ссылка
Ich würde Netzwerkkommunikation in einem Hintergrundthread durchführen, so dass es nichts anderes in Ihrer Anwendung blockiert.
Das Problem mit BeginReceive ist, dass Sie EndReceive an einem bestimmten Punkt aufrufen müssen (sonst haben Sie Warte-Griffe nur herum) - und der Aufruf von EndReceive wird blockiert, bis der Empfang beendet ist. Deshalb ist es einfacher, die Kommunikation einfach auf einen anderen Thread zu legen.
Sie müssen Netzwerkoperationen, Dateimanipulationen und andere Dinge durchführen, die von anderen Dingen abhängig sind, als von Ihrem eigenen Programm in einem anderen Thread (oder Aufgabe ), weil sie Ihr Programm einfrieren können. Der Grund dafür ist, dass Ihr Code sequenziell ausgeführt wird.
Sie haben es in einer Schleife verwendet, die nicht in Ordnung ist. Wenn BeginRecieve
callback aufgerufen wird, sollten Sie es erneut aufrufen. Sehen Sie sich den folgenden Code an:
Tags und Links c# udpclient beginreceive