Hallo, ich möchte für eine Ping Anwendung den Asynchron-Modus benutzen. In Visual Studio C# gibt es hierfür die Methode SendAsync von der Klasse Ping. Sobald ich in einer For-Schleife mehrere Ping mit der Methode SendAsync absetzen möchte, erscheint beim zweiten Aufruf folgende Fehlermeldung: Es läuft bereits ein asynchroner Aufruf. Er muss abgeschlossen oder abgebrochen werden, bevor Sie diese Methode aufrufen können. Mir ist nun nicht klar was ich falsch mache bzw. wie ich dieses Problem beheben könnte.
Anwender schrieb: > Mir ist nun nicht klar was ich falsch mache bzw. wie ich dieses Problem > beheben könnte. eventuell muss du ja mehre Objekte anlegen.
Das kann doch nicht sein das ich mehrere Objekte von Ping anlegen muss. Initialisierung
1 | Ping p = new Ping(); |
2 | AutoResetEvent waiter = new AutoResetEvent(false); |
3 | p.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback); |
Button drücken
1 | while(...) |
2 | {
|
3 | p.SendAsync(sLine, 1000, Encoding.ASCII.GetBytes(data), options, waiter); |
Callback für den Empfang
1 | private static void PingCompletedCallback(object sender, PingCompletedEventArgs e) |
2 | {
|
3 | // do something
|
4 | }
|
Anwender schrieb: > Das kann doch nicht sein das ich mehrere Objekte von Ping anlegen muss. und warum nicht?
Hmmm, ok so hab ich mir das aber nicht vorgestellt. Für einen nicht blockierenden Ping Mechanismus sollte die Methode SendAsync eingesetzt werden. Wenn ich die Send Methode verwende, dann wird die Anwendung blockiert bis ein Timeout eintrifft.
Anwender schrieb: > Hmmm, ok so hab ich mir das aber nicht vorgestellt. > Für einen nicht blockierenden Ping Mechanismus sollte die Methode > SendAsync eingesetzt werden. Wenn ich die Send Methode verwende, dann > wird die Anwendung blockiert bis ein Timeout eintrifft. wo ist das Problem mehre Objekte anzulegen und dann SendAsync aufzurufen=
Anwender schrieb: > Hmmm, ok so hab ich mir das aber nicht vorgestellt. Naja, jetzt weißt du es ja ;-) Anwender schrieb: > Für einen nicht blockierenden Ping Mechanismus sollte die Methode > SendAsync eingesetzt werden. Wenn ich die Send Methode verwende, dann > wird die Anwendung blockiert bis ein Timeout eintrifft. Richtig. SendAsync arbeitet asynchron.
Müsste nach der Ausführung von SendAsync tun? Muss danach das Objekt wieder beendet werden?
Ich hab mir jetzt mal folgendes überlegt bezüglich nicht blockierender Betrieb mit der Send Methode. Sobald ein TimeOut aufschlagt soll ein Event ausgelöst werden. In einem zusätzlichen Thread soll geprüft werden ob ein Event aufgetrten ist oder nicht. Wenn ja soll der TimeOut weiter behandelt werden. Macht dieser Weg Sinn? Ist damit die Blockierung ausgehebelt?
Anwender schrieb: > Müsste nach der Ausführung von SendAsync tun? Ist das eine Frage? Falls ja: Hä? :-) Falls ich deine zweite Frage richtig verstehe: Nachdem dein Callback aufgerufen wurde, kannst du das Ping-Objekt vom Garbage Collector abräumen lassen (falls du es nicht mehr brauchst).
Anwender schrieb: > Ich hab mir jetzt mal folgendes überlegt bezüglich nicht blockierender > Betrieb mit der Send Methode. Das klingt alles ziemlich strange. Was GENAU willst du denn erreichen? Spontan würde mir so was einfallen:
1 | class Pinger |
2 | {
|
3 | private readonly List<Ping> mActivePings = new List<Ping>(); |
4 | |
5 | |
6 | public void SendPings(string[] adresses) |
7 | {
|
8 | foreach (var address in adresses) |
9 | {
|
10 | var p = new Ping(); |
11 | p.PingCompleted += PingCompletedCallback; |
12 | p.SendPingAsync(address); |
13 | }
|
14 | }
|
15 | |
16 | private void PingCompletedCallback(object sender, PingCompletedEventArgs e) |
17 | {
|
18 | var p = sender as Ping; |
19 | if (p == null) return; |
20 | |
21 | // Handle ping...
|
22 | Console.WriteLine(e.Reply != null ? "Got a reply" : "Got no reply"); |
23 | |
24 | mActivePings.Remove(p); |
25 | }
|
26 | }
|
:
Bearbeitet durch User
Boris P. schrieb: > Spontan würde mir so was einfallen: ich denke man kann sogar auf die mActivePings verzichten.
Peter II schrieb: > ich denke man kann sogar auf die mActivePings verzichten. Hast Recht. Irgendwas wollte ich noch damit machen (z.B. prüfen, ob alle Pings durch sind), hab's aber dann vergessen... Editieren geht leider nicht mehr...
Erstmal vielen Dank für eure Hilfe. Wenn während der Ping Kommunikation einen TimeOut aufschlägt, soll nicht nach der TimeOut Zeit ein neuer Ping gesendet werden, sondern fortlaufend. Bisher ist es so, dass sobald ein TimeOut kommt wird dieser bearbeitet und erst danach erfolgt wieder ein Ping. Wie könnte dies umgesetzt werden?
Hallo, bin nun dabei den Asynchronmechanismus von der Ping Klasse zu testen. In einer While Schleife sende ich nacheinander 2 Ping Request Nachrichten. Wenn ich einen Teilnehmer unterbreche, dann wird in die Callback Methode gesprungen. Wie kann man nun in der Callback Methode feststellen, welche Request Nachricht nicht angekommen ist? Von welcher IP? Das wäre nämlich sehr hilfreich wenn man wissen möchte von welchem Teilnemer keine Bestätigung zurückkommt.
Anwender schrieb: > Wie kann man nun in der Callback Methode feststellen, welche > Request Nachricht nicht angekommen ist? du hast doch das Sender objekt. Damit kommst du an das Ping-Objekt ran.
Schau dir doch mal die Beispiele hier an: http://stackoverflow.com/questions/22078510/how-can-i-make-many-pings-asynchronously-at-the-same-time Das sollte hoffentlich weiterhelfen :-)
Anwender schrieb: > Im Sender Objekt kann ich keine IP Adresse finden. du musst das Sender object erst auf ein Ping objekt casten.
Peter II schrieb: > du hast doch das Sender objekt. Damit kommst du an das Ping-Objekt ran. Die IP steht aber vermutlich nicht im Ping Objekt, oder? Vielleicht noch mal mein Beispiel von oben, ein bisschen angepasst:
1 | class Pinger |
2 | {
|
3 | private readonly Dictionary<Ping, string> mActivePings = new Dictionary<Ping, string>(); |
4 | |
5 | |
6 | public void SendPings(string[] adresses) |
7 | {
|
8 | foreach (var address in adresses) |
9 | {
|
10 | var p = new Ping(); |
11 | p.PingCompleted += PingCompletedCallback; |
12 | p.SendPingAsync(address); |
13 | |
14 | mActivePings.Add(p, address); |
15 | }
|
16 | }
|
17 | |
18 | private void PingCompletedCallback(object sender, PingCompletedEventArgs e) |
19 | {
|
20 | var p = sender as Ping; |
21 | if (p == null) return; |
22 | |
23 | // Handle ping...
|
24 | Console.WriteLine(e.Reply != null ? "Got a reply from " + mActivePings[p] : "Got no reply from " + mActivePings[p]); |
25 | mActivePings.Remove(p); |
26 | }
|
27 | }
|
:
Bearbeitet durch User
Und im Visual Studio hast du dein Projekt auch entsprechend eingestellt (Project -> Eigenschaften -> Target framework)?
Welches Framework sollte ich installieren? .NET Framework 4.6 .NET Framework 4.6 Runtime Visual Studio Community 2013 (free) Visual Studio Express 2013 (free) .NET Framework 4.5.2 .NET Framework 4.5.2 Runtime .NET Framework 4.5.2 Developer Pack .NET Framework 4.5.2 Language Packs .NET Framework 4.5.1 Included in Visual Studio 2013 .NET Framework 4.5.1 Runtime .NET Framework 4.5.1 Developer Pack Windows Software Development Kit for Windows 8.1 .NET Framework 4.5 Included in Visual Studio 2013 .NET Framework 4.5 Runtime Windows Software Development Kit (SDK) for Windows 8
Bei Visual Studio sollte ja schon alles dabei sein. Hast du hier die neueste Version (2013) installiert?
Hallo, ich verwende nun die SendAsync Methode. Damit kann ebenfalls ein Ping versendet werden. Den asynchron Ping Mechanismus ist in einer Klasse gekapselt. Die Hauptapplikation mit der grafischen Auswertung soll nun auf die Callback Methode PingCompletedCallback zugreifen können. Wie könnte sowas realisiert werden?
1 | private void PingCompletedCallback(object sender, PingCompletedEventArgs e) |
2 | {
|
3 | ...
|
4 | }
|
Anwender schrieb: > Die > Hauptapplikation mit der grafischen Auswertung soll nun auf die Callback > Methode PingCompletedCallback zugreifen können. Wie könnte sowas > realisiert werden? Öhm? Es sollte eher umgekehrt sein: der Callback greift auf die GUI zu, um das Ergebnis des Pings dort anzuzeigen. Ist es das was du meinst?
Anwender schrieb: > Den asynchron Ping Mechanismus ist in einer Klasse gekapselt. Gut soweit. > Die Hauptapplikation mit der grafischen Auswertung soll nun auf die > Callback Methode PingCompletedCallback zugreifen können. Das ergibt nun überhaupt keinen Sinn. Implementiere doch ein Event in deiner Ping-Klasse und hänge dort ein, was du willst.
Ich habe ganz vergessen zu sagen, das ich noch mit der Microsoft Visual Studio 2010 Prof. Version arbeite. Ist das ein Bug vom 2010 Visual Studio, dass man die IP Adresse in der Callback Methode beim Timeout nicht auslesen kann?
Anwender schrieb: > Version arbeite. Ist das ein Bug vom 2010 Visual > Studio, dass man die IP Adresse in der Callback Methode beim Timeout > nicht auslesen kann? nein bestimmt nicht. Außerdem ist das Studio nur die IDE. Wenn überhaupt ist der Compiler für Fehler verantwortlich. Zur not must du dir halt für jedes Ping-Objekt die IP selber merken, und in der callback bekommt du das Ping-Objekt ja als Sender und dann einfach in der eigenen Liste nachschauen.
Peter II schrieb: > Zur not must du dir halt für jedes Ping-Objekt die IP selber merken, und > in der callback bekommt du das Ping-Objekt ja als Sender und dann > einfach in der eigenen Liste nachschauen. So kann man's machen. Das habe ich ja in meinem zweiten Beispiel oben auch so gemacht. Kleiner Tipp am Rande: Ich glaube es gibt da noch ein paar Grundlgenede Verständnisprobleme deinerseits. Vielleicht solltest du mal erklären, was du überhaupt vorhast. Denn ich denke du verrenst dich da in Details, obwohl es vielleicht viel einfacher ginge... Und mal ein paar Tutorials zu C#, .NET und Visual Studio durchgehen, dann sollte dir das Ganze deutlich leichter fallen.
Guten Morgen, ich habe nun keine eigene Ping Klasse erstellt. Die Methode SendPing sowie die Callback Methode rufe ich in der GUI Applikation auf. Das funktioniert soweit. Allerdings würde es mich trotzdem interessieren wie man die Implementierung realisieren müsste, wenn in der Ping Klasse bei der Ausführung der Callback Methode einen Event erzeugt werden kann, der dann in der GUI Applikation was tun soll.
Anwender schrieb: > Die Methode SendPing > sowie die Callback Methode rufe ich in der GUI Applikation auf. Ich weiß nicht, ob du dich nur falsch ausgedrückt hast, aber da du oben schon das hier wolltest: > Die Hauptapplikation mit der grafischen Auswertung soll nun auf die > Callback Methode PingCompletedCallback zugreifen können. PingCompletedCallback sollst du nicht aufrufen, die Methode wird aufgerufen (und du kannst dann darin etwas machen). Siehe auch Boris P. schrieb: > Es sollte eher umgekehrt sein: der Callback greift auf die GUI zu, > um das Ergebnis des Pings dort anzuzeigen. Ist es das was du meinst?
Mit der asynchrone Sendmethode habe ich einen Fehler entdeckt. Sobald ich einen Timeout (zeitlich sehr kurz) provoziere, dann wird zweimal in die Callback Methode reingesprungen. Es soll aber nur einmal ein Timeout ausgelöst werden. Ich sende jede Sekunde mit einem Timer den Ping. Die Timeout Zeit beträgt 1,2 Sekunden. Woran könnte hier das Problem liegen? Ist dieses Fehlerverhalten allgemein bekannt?
Natürlich veranlasst das Programm, die Ausführung der Callback Methode "PingCompletedCallback". Ich führe diese Methode nicht selber aus. Hab mich oben etwas missverständlich ausgedrückt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.