Hallo!
Ich lausche in meinem Programm einer Art Börsentickerstream. In meinem Fenster starte ich in der button_click(..) die Funktion StartBitcoinchartsTicker(). Diese startet nun in einem neuen Thread die bitcoinchartlistener() funktion die nun in einer Endlosschleife den Stream abhört. Der Thread wird gespeichert als ThreadX
Wenn ich mein Programmfenster schließe und damit das Programm beenden will, dann "lebt" bitcoinchartslistener einfach weiter. Auch ein ThreadX.abort() bringt nichts. in der Receive funktion kommt dieser Befehl sich zu beenden wohl nicht zur ausführung.
Wie kann ich mein Programm vollständig beenden?
Ich habe folgenden Code:
static bool isBitcoinchartsTickerRunning = false;
public static System.Threading.Thread StartBitcoinchartsTicker()
{
if (isBitcoinchartsTickerRunning == false)
{
return run(() => { bitcoinchartlistener(); });
}
return null;
}
static BitCoinChartsData bitcoinchartlistener()
{
Socket sock = null;
IPHostEntry hostEntry = null;
hostEntry = Dns.GetHostEntry("bitcoincharts.com");
// Nutze die Eigenschaft AddressFamily von IPEndPoint um Konflikte zwischen
// IPv4 und IPv6zu vermeiden. Gehe dazu die Adressliste mit einer Schleife durch.
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipo = new IPEndPoint(address, 27007);
Socket tempSocket = new Socket(ipo.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
tempSocket.Connect(ipo);
if (tempSocket.Connected)
{
sock = tempSocket;
break;
}
else
{
continue;
}
}
Byte[] bytesReceived = new Byte[94096];
// Instanziere ein gültiges Socket Objekt mit den übergebenen Argumenten
if (sock == null)
{
if (OnError != null)
{OnError("Could not connect to Bitcoinchart-Datastream");}
}
isBitcoinchartsTickerRunning=true;
int bytes = 0;
// Empfange die Daten und konvertiere sie
do
{
bytes = sock.Receive(bytesReceived, bytesReceived.Length, SocketFlags.None);
// kovertiere die Byte Daten in einen string
//page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
if(OnNewBitcoinchartData!=null)
{
string JSON = Encoding.ASCII.GetString(bytesReceived, 0, bytes);
string[] JSONs = JSON.Split(new string[]{"\0"},StringSplitOptions.RemoveEmptyEntries);
foreach(string JS in JSONs)
{
JS.Replace("\0","");
OnNewBitcoinchartData(new BitCoinChartsData(JS));
}
}
} while (bytes > 0);
// Unterbinde alle weiteren Send() und Receive() Aktivitäten am Socket
sock.Shutdown(SocketShutdown.Both);
sock.Close();
if (OnError != null)
{ OnError("Could not connect to Bitcoinchart-Datastream"); }
isBitcoinchartsTickerRunning = false;
return null;
}
Nevu - Intelligente Maschinen, die Zukunft alles rund um das Thema Künstliche Intelligenz!
Ich habe eine (in meinen Augen nicht elegante) Lösung gefunden:
ich platziere ein
while(sock.Available == 0)
{
System.Threading.Thread.Sleep(100);
}
vor das Recive.
Bitte dennoch um Ideen wie man es besser machen könnte 😃
Nevu - Intelligente Maschinen, die Zukunft alles rund um das Thema Künstliche Intelligenz!
Hi,
ein paar Vorschläge:*Socket.Receive müsste eine Überladung haben, in der man einen Timeout angeben kann...? So kannst du zum Beispiel immer nach einer bestimmten Zeit prüfen, ob der Thread abgebrochen werden soll *Bei dem Thread das Background-Flag auf true setzen, dann wird er automatisch Beendet, wenn du deine Anwendung schließt *Thread.Abort nicht verwenden, sofern dus wirklich nicht anders hin bekommst
Gruß
Roland
Hallo,
weitere Vorschläge:
Du musst auf den Socket die Socket.ReceiveTimeout Property auf einen Wert setzen, so dass ein Timeout eine Socket-Exception auslöst.
Ansonsten solltest Du entweder einen Task verwenden oder einen echten Thread starten und die vorher beschriebene BackGround Property setzen.