Forum: PC-Programmierung Ping mit Visual Studio C#


von Anwender (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Anwender (Gast)


Lesenswert?

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
}

von Peter II (Gast)


Lesenswert?

Anwender schrieb:
> Das kann doch nicht sein das ich mehrere Objekte von Ping anlegen muss.

und warum nicht?

von Anwender (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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=

von Borislav B. (boris_b)


Lesenswert?

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.

von Anwender (Gast)


Lesenswert?

Müsste nach der Ausführung von SendAsync tun? Muss danach das Objekt 
wieder beendet werden?

von Anwender (Gast)


Lesenswert?

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?

von Borislav B. (boris_b)


Lesenswert?

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).

von Borislav B. (boris_b)


Lesenswert?

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
von Peter II (Gast)


Lesenswert?

Boris P. schrieb:
> Spontan würde mir so was einfallen:

ich denke man kann sogar auf die mActivePings  verzichten.

von Borislav B. (boris_b)


Lesenswert?

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...

von Anwender (Gast)


Lesenswert?

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?

von Anwender (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Anwender (Gast)


Lesenswert?

Im Sender Objekt kann ich keine IP Adresse finden.

von Borislav B. (boris_b)


Lesenswert?

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 :-)

von Peter II (Gast)


Lesenswert?

Anwender schrieb:
> Im Sender Objekt kann ich keine IP Adresse finden.

du musst das Sender object erst auf ein Ping objekt casten.

von Borislav B. (boris_b)


Lesenswert?

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
von Anwender (Gast)


Lesenswert?

Hallo,

die Funktion SendPingAsync existiert bei mir nicht.

von Borislav B. (boris_b)


Lesenswert?

Meine Vermutung: nicht gegen .NET 4.5 gebaut?

von Anwender (Gast)


Lesenswert?

Version von .NET: 4.5.50938 SP 1Rel

von Borislav B. (boris_b)


Lesenswert?

Und im Visual Studio hast du dein Projekt auch entsprechend eingestellt 
(Project -> Eigenschaften -> Target framework)?

von Anwender (Gast)


Lesenswert?

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

von Borislav B. (boris_b)


Lesenswert?

Bei Visual Studio sollte ja schon alles dabei sein.
Hast du hier die neueste Version (2013) installiert?

von Anwender (Gast)


Lesenswert?

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
}

von Borislav B. (boris_b)


Lesenswert?

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?

von Halbaddierer (Gast)


Lesenswert?

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.

von Anwender (Gast)


Lesenswert?

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?

von Peter II (Gast)


Lesenswert?

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.

von Borislav B. (boris_b)


Lesenswert?

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.

von Anwender (Gast)


Lesenswert?

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.

von Halbbekleideter (Gast)


Lesenswert?

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?

von Halbfertiger (Gast)


Lesenswert?

Benutzt du eigentlich Windows Forms oder WPF?

von Anwender (Gast)


Lesenswert?

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?

von Anwender (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.