Laden...

Sicherer Restart einer Console-App

Erstellt von Nullpunkt vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.010 Views
N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren
Sicherer Restart einer Console-App

hi,
ich habe ein konsolen-prog welches restart-fähig sein soll.

folgende methode wird im für den restart aufgerufen:

// Listener stoppen
listener.Stop();

// Tool neu starten
System.Diagnostics.Process.Start("ConsoleApplication2.exe", "safemode");

// Diese Instanz killen
Environment.Exit(Environment.ExitCode);

nun, beim restart gibts dann gleich wieder eine exception:
"Only one usage of each socket....."

ich habe mir dann gedacht, der listener brauche evt seine zeit bis er den port
wirklich frei gibt. also habe ich beim neustart der app in der main zu beginn
einen sleep von 3 sekunden geschrieben.

das reicht aber anscheinend nicht. die exception feuert jedesmal wieder aufs neue.

meiner meinung nach wäre das listener.Stop nicht mal nötig, da ich ja sowieso
3 sekunden warte und die erste instanz des proggies ja sowieso zu ist.

wo also könnte den mein denkfehler liegen?

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

zumindest mal die Vermutliche Ursache:

Die Stop-Methode schließt außerdem den zugrunde liegenden Socket und erstellt einen neuen Socket für den TcpListener

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

hi herbivore,
besten dank!

ich habe also nun folgendes probiert:

// Listener zerstören
listener = null;

das brachte wiederum die selbe exception.

dann habe ich mir gedacht, ich instantiiere den listener
doch einfach neu auf einen anderen port. dann sollte ja eigentlich gar nichts
mehr schief gehen können:


listener = new TcpListener(IPAddress.Any, ein_anderer_port);

auch mit dieser anpassung stehe ich vor derselben exception.

gehe ich vielleicht den ganz falschen weg?

ich habe gesehen dass es bei den windows.forms ja Application.Restart()
gibt. etwas ähnliches habe ich für consolenproggies nicht gefunden, deshalb
hab ichs wie beschrieben probiert.

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

mit listener = null; setzt du nur die Variable auf null. Das Objekt lebt erstmal weiter, bis der GC erkennt, dass es keine Referenz mehr darauf gibt.

mit listener = new TcpListener(IPAddress.Any, ein_anderer_port); setzt du nur die Variable auf eine neue Referenz. Das alte Objekt lebt erstmal weiter, bis der GC erkennt, dass es keine Referenz mehr darauf gibt.

Ich denke Application.Restart müsste es auch für Konsolenanwendungen tun.

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

hi,
vielen dank für deine erläuterung.

wenn ich nichts falsch verstanden habe, dann finde ich Application.Restart()
im namespace windows.forms

msdn

da die app auch auf linux über mono laufen soll und mono noch nicht so fit
ist in sachen windows.forms möchte ich eben auf diese verzichten, wenns anders geht..

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

man kann so ein Restart mit Process.Start sicher auch selber programmieren.

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

aber herbivore,
das ist ja genau das was ich im ersten post beschrieben probiert habe.

das war ja mein urspüngliches ziel.

nur klappts ja anscheinend nicht...

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

dann probier doch erstmal, ob es überhaupt mit Application.Restart geht.

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

hi,
also ich restarte nun mit Application.Restart() und erhalte
aber noch immer den selben fehler.

hier einmal die ganze fehlermeldung:


\************************
19.04.2007 12:29:34
\************************
Fehler beim Horchen
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at System.Net.Sockets.TcpListener.Start(Int32 backlog)
   at System.Net.Sockets.TcpListener.Start()
   at ConsoleApplication2.Program.Main(String[] args)

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

ok, dann musst du wohl den Restart synchronisieren. Am besten, du wartest mit Process.HasExited darauf, dass der erste Thread wirklich gestorben ist. Wenn es dann immer noch nicht geht, dann weiß ich auch nicht.

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

hi,
bevor ich den ersten prozess nun beende,
starte ich den zweiten und sende als parameter die prozess-id
mit.

zu beginn der main() frage ich dann nach den argumenten und falls
dort eine id drin steckt behandle ich diese.

das sieht so aus:

static void restart_app()
{
    // Tool neu starten
    System.Diagnostics.Process.Start("ConsoleApplication2.exe", System.Diagnostics.Process.GetCurrentProcess().Id.ToString());

    // Diese Anwendung verlassen
    Environment.Exit(Environment.ExitCode);
}

und in der main:

if (args.Length > 0)
{
    if (System.Diagnostics.Process.GetProcessesByName("ConsoleApplication2").Length>1)
    {
        System.Diagnostics.Process.GetProcessById(Convert.ToInt32(args[0])).Kill();
    }
}

nur wirft kill eben auch wieder ne exception, wenn der prozess bereits am schliessen
ist. dann habe ich noch hasexited, waitforexit und anstatt kill -> dispose probiert.
irgendwie meckert er jedesmal.

irgendwas wie tryKill oder so wär schmuck..

naja, falls keine ideen mehr vorhanden sind, muss ich wohl oder übel ein
kontroll-programm machen, dass mir diese app überwacht und gegebenfalls neu startet..

wollte das eigentlich umgehen.

mfg nullpunkt

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Nullpunkt,

irgendwie meckert er jedesmal.

die genauen Fehlermeldungen wären hilfreich.

herbivore

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

ich wollte gerade eben die fehlermeldungen zusammenstellen,
als ich merkte, dass die app bei einem fehler etwa 10mal neu gestartet wird.
beim von mir provozierten fehler ist jeder thread fehlerhaft und fordert
dann den neustart.

ich muss zuerst mal das in den griff kriegen.

melde mich.

nullpunkt

N
Nullpunkt Themenstarter:in
277 Beiträge seit 2005
vor 17 Jahren

also,
der fehler lag darin, das jeder thread den reboot ausgelöst hatte.
nun funktioniert die sache tiptop so wie in meinem vor-vorherigen post.

danke für dein geduld : )

mfg nullpunkt