[英]Way to close TCP Connection and Exit Application
這是一個TCP程序,該程序從TCP連接接收數據,然后解析該數據並將其傳輸到另一個TCP連接。 當我退出應用程序時,它不起作用。 它將作為進程保留在系統中。
由於我不是一個非常有經驗的開發人員,請有人可以幫助我找到此代碼中的錯誤。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace Machine_Feeder
{
public partial class FeederControlMonitor : Form
{
TcpListener Listener = null;
public string Status = string.Empty;
public Thread T = null;
public FeederControlMonitor()
{
InitializeComponent();
}
private void FeederControlMonitor_Load(object sender, EventArgs e)
{
txtStatus.Text = "Feeder waiting for data...";
ThreadStart Ts = new ThreadStart(StartReceiving);
T = new Thread(Ts);
T.Start();
}
public void StartReceiving()
{
ReceiveTCP(9100);
}
public void ReceiveTCP(int portN)
{
try
{
Listener = new TcpListener(IPAddress.Any, portN);
Listener.Start();
}
catch (Exception ex)
{
File.WriteAllText(@"C:\\Drive\\ex.txt", ex.Message);
Console.WriteLine(ex.Message);
}
try
{
while (true)
{
Socket client = Listener.AcceptSocket();
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[10000];
int size = client.Receive(data);
ParseData(System.Text.Encoding.Default.GetString(data));
client.Close();
});
childSocketThread.Start();
}
Listener.Stop();
}
catch (Exception ex)
{
File.WriteAllText(@"C:\\Drive\\ex.txt", ex.Message);
}
}
public void ParseData(string data)
{
var useFulData = data.Substring(data.IndexOf("F1")).Replace(" ", " ");// Space
useFulData = useFulData.Remove(useFulData.IndexOf("<ETX>"));
string[] delimeters = { "<DEL>", "<ESC>" };
var listOfValues = useFulData.Split(delimeters, StringSplitOptions.None).ToList();
int pos = 0;
for (int i = 1; i < listOfValues.Count; i += 2, pos++)
{
listOfValues[pos] = listOfValues[i];
}
listOfValues.RemoveRange(pos, listOfValues.Count - pos);
txtHealthCard.Invoke((Action)delegate { txtHealthCard.Text = listOfValues[0]; });
txtCID.Invoke((Action)delegate { txtCID.Text = listOfValues[1]; });
txtMedicalFitLocation.Invoke((Action)delegate { txtMedicalFitLocation.Text = listOfValues[2]; });
txtGender.Invoke((Action)delegate { txtGender.Text = listOfValues[3]; });
txtAge.Invoke((Action)delegate { txtAge.Text = listOfValues[4]; });
txtPatientName.Invoke((Action)delegate { txtPatientName.Text = listOfValues[5]; });
MyProtocolMaker(listOfValues[5],
listOfValues[4],
listOfValues[2],
listOfValues[3],
listOfValues[8],
listOfValues[1],
listOfValues[10],
);
}
private void btnExit_Click(object sender, EventArgs e)
{
Listener.Stop();
T.Abort();
this.Close();
}
private void MyProtocolMaker(
string patientName,
string patientAge,
string mfitLocation,
string gender,
string healthCardNo,
)
{
string feederInfo = "^^^P^PI" + healthCardNo + "^PN" + patientName + "^PA" + patientAge + "^PS" + gender + "^P7" + mfitLocation +"^_SS^^^_S";
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient("127.0.0.1", 8001);
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(feederInfo);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
serverStream.Close();
clientSocket.Close();
}
private void FeederControlMonitor_FormClosing(object sender, FormClosingEventArgs e)
{
Listener.Stop();
T.Abort();
this.Close();
}
}
}
您的問題是,您正在線程中創建線程。 這些線程使應用程序保持活動狀態。 嘗試將它們標記為后台線程:( 這是紅色磁帶解決方案)
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[10000];
int size = client.Receive(data); // <-- the thread hangs on these and will block termination
ParseData(System.Text.Encoding.Default.GetString(data));
client.Close();
});
childSocketThread.IsBackground = true; // <---
childSocketThread.Start();
當線程未標記為后台(默認)時 ,它們將阻止應用程序終止。 您應該創建一個列表來存儲客戶端線程,以便可以很好地退出這些線程。
除非沒有其他方法,否則切勿中止線程。 而不是中止,您應該退出線程中的while
循環。
最好的方法是使用ManualResetEvent
:
領域:
private ManualResetEvent _terminating = new ManualResetEvent(false);
在線程中:
while (_terminating.WaitOne(0))
{
// thread code
}
在出口:
_terminating.Set();
T.Join();
旁注:TCP正在流式傳輸,因此僅讀取10k字節的字節就不能保證完整的數據包。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.