System Invalid Operation Exception error - c#

Yesterday I have created two forms, the first form listen requests of client out network, the second form is form alert (MessageBox custom) like MessageBox, but when a client sends a connection request to the first form, affter the form second will show, but affter click on any button to close form and I received an message below:
Title: System.InvalidOperationException
Details:
The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone).
The First From:
//Nhận các yêu cầu và kiểm tra và gửi phản hồi
private void OnReceive(IAsyncResult ar)
{
try
{
EndPoint receivedFromEP = new IPEndPoint(IPAddress.Any, 0);
//Get the IP from where we got a message.
clientSocket.EndReceiveFrom(ar, ref receivedFromEP);
//Convert the bytes received into an object of type Data.
Data(byteData);
//Act according to the received message.
switch (cmdCommand)
{
//We have an incoming call.
case Command.Invite:
{
if (bIsCallActive == false)
{
//We have no active call.
//Ask the user to accept the call or not.
DialogResult result = ThongBaoCoDienThoai.HienHopThoai(strName);
if (result == DialogResult.Yes)
{
//SendMessage(Command.OK, receivedFromEP);
//Bắt đầu kết nôi
//**********************************GOI PHUONg THUC GUI NHAN DONG BO AM THANH****************
}
else
{
//The call is declined. Send a busy response.
//SendMessage(Command.Busy, receivedFromEP);
}
}
else
{
//We already have an existing call. Send a busy response.
SendMessage(Command.Busy, receivedFromEP);
}
break;
}
//OK is received in response to an Invite.
case Command.OK:
{
//Start a call.
break;
}
//Remote party is busy.
case Command.Busy:
{
MessageBox.Show("User busy.", "VoiceChat", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
break;
}
case Command.Bye:
{
//Check if the Bye command has indeed come from the user/IP with which we have
//a call established. This is used to prevent other users from sending a Bye, which
//would otherwise end the call.
if (receivedFromEP.Equals(otherPartyEP) == true)
{
//End the call.
}
break;
}
}
byteData = new byte[1024];
//Get ready to receive more commands.
clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref receivedFromEP, new AsyncCallback(OnReceive), null);
}
catch (Exception ex)
{
MessageBox.Show("OnReceive: " + ex.Message, "Error");
}
}
The Second Form:
static ThongBaoCoDienThoai tbcdt;
static DialogResult kq = DialogResult.No;
private Timer thoiGian;
int henGioTat; //Hẹn thời gian tắt form
SoundPlayer player; //Khởi tạo thiết bị phát (Loa)
public ThongBaoCoDienThoai()
{
InitializeComponent();
try
{
henGioTat = 30;
thoiGian = new Timer();
thoiGian.Interval = 1000;
thoiGian.Enabled = true;
thoiGian.Start();
thoiGian.Tick += new EventHandler(this.thoiGian_Tick);
//Hiển thị hộp thông báo ở góc màng hình dưới bên phải
Rectangle r = Screen.PrimaryScreen.WorkingArea;
this.StartPosition = FormStartPosition.Manual;
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - this.Width, Screen.PrimaryScreen.WorkingArea.Height - this.Height);
//Phát âm thành khi form được mở
player = new SoundPlayer(Properties.Resources.ringing);
player.Load();
player.PlayLooping();
}
catch (Exception ex)
{
MessageBox.Show("ThongBaoCoDienThoai_Load :" + ex.Message, "Error");
}
}
public static DialogResult HienHopThoai(string tenNguoiGoi)
{
try
{
tbcdt = new ThongBaoCoDienThoai();
tbcdt.lbThongBao.Text = tenNguoiGoi + " đang gọi........";
tbcdt.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show("HienHopThoai: "+ex.Message,"Error");
}
return kq;
}
private void btHuy_Click(object sender, EventArgs e)
{
tbcdt.thoiGian.Stop();
tbcdt.thoiGian.Dispose();
kq = DialogResult.No;
tbcdt.Dispose();
}
private void btNhan_Click(object sender, EventArgs e)
{
ThongBaoCoDienThoai tbcdt = new ThongBaoCoDienThoai();
alertControl1.Show(tbcdt);
tbcdt.thoiGian.Stop();
tbcdt.thoiGian.Dispose();
kq = DialogResult.Yes;
tbcdt.Dispose();
}
private void thoiGian_Tick(object sender, EventArgs e)
{
henGioTat--;
if (henGioTat == 0)
{
tbcdt.thoiGian.Stop();
tbcdt.thoiGian.Dispose();
tbcdt.Dispose();
}
}
private void ThongBaoCoDienThoai_FormClosing(object sender, FormClosingEventArgs e)
{
player.Stop();
}

Related

Pass value two textbox's from one variable value

I have an encoder connected from Siemens PLC with data block "DB1.DBD56".
My problem is, the two textbox has the same result or value.
Scenario:
Read Before 1seconds and
Read After 1seconds
I want the result like this:
[For reference]
(https://i.stack.imgur.com/HK9zU.png)
[PLC Ladder]
(https://i.stack.imgur.com/kGN62.png)
#region EVENT TO START READING THE ENCODER
private void timer_anvilState_Tick(object sender, EventArgs e)
{
try
{
Edata_convertion();
read_lastweld_result();
bool anvilState = (bool)plc_s7_1200.Read("DB1.DBX68.4");
if (plc_s7_1200.IsConnected)
{
if (anvilState == true)
{
timer_OneCycleProcess.Start(); //STATE MACHINE TIMER
}
else
{
timer_OneCycleProcess.Stop();
command = "IDLE";
}
}
}
catch (Exception ex)
{
MessageBox.Show("Please check between PC and PLC connection " + "\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#region READ BEFORE
public void Read_Before()
{
if (plc_s7_1200.IsConnected)
{
bool anvilState = (bool)plc_s7_1200.Read("DB1.DBX68.4");
if (anvilState == true)
{
string Edata = string.Format("{0:0.0}", convertTomm);
txtbefore.Text = Edata;
}
}
}
#endregion
#region READ AFTER
public void Read_After()
{
bool gen_US_on = (bool)plc_s7_1200.Read("DB1.DBX78.2");
if (gen_US_on == true)
{
string Edata = string.Format("{0:0.0}", convertTomm);
txtafterWeld.Text = Edata;
}
}
#endregion
Here's my solution.
Only revised the PLC ladder as stated my replied at comment section.
https://i.stack.imgur.com/GUBtg.png
My C# program nothing changes.
Sharing my basic state machine code
#region ONE CYCLE PROCESS
private void timer_OneCycleProcess_Tick(object sender, EventArgs e)
{
switch (command)
{
case "IDLE":
command = "BEFORE";
break;
case "BEFORE":
before();
command = "AFTER";
break;
case "AFTER":
after();
prev_result();
read_maintenanceCounter();
read_outputCounter();
command = "SAVE";
break;
case "SAVE":
command = "STOP";
save();
save_history();
break;
case "STOP":
timer_OneCycleProcess.Stop();
plc_s7_1200.Write("DB1.DBX38.0", 0);
break;
default:
break;
}
}
#endregion

nodejs and c# combinationquery

I am building an application , in which I need to have a c# server and nodejs client. I have built the components , but I am always getting ECONNREFUSED error. any leads when I can except this error?
FYI,
I am able to connect to c# server from c# client. similarly. I am able to connect to nodejs tcp server from nodejs tcp client. however the I am facing error with this mixture.
hey sorry for not adding code earlier.
the following is the c# server code:
using System;
using System.Text;
using AsyncClientServerLib.Server;
using System.Net;
using AsyncClientServerLib.Message;
using SocketServerLib.SocketHandler;
using SocketServerLib.Server;
namespace TestApp
{
delegate void SetTextCallback(string text);
public partial class FormServer : Form
{
private BasicSocketServer server = null;
private Guid serverGuid = Guid.Empty;
public FormServer()
{
InitializeComponent();
}
protected override void OnClosed(EventArgs e)
{
if (this.server != null)
{
this.server.Dispose();
}
base.OnClosed(e);
}
private void buttonStart_Click(object sender, EventArgs e)
{
this.serverGuid = Guid.NewGuid();
this.server = new BasicSocketServer();
this.server.ReceiveMessageEvent += new SocketServerLib.SocketHandler.ReceiveMessageDelegate(server_ReceiveMessageEvent);
this.server.ConnectionEvent += new SocketConnectionDelegate(server_ConnectionEvent);
this.server.CloseConnectionEvent += new SocketConnectionDelegate(server_CloseConnectionEvent);
this.server.Init(new IPEndPoint(IPAddress.Loopback, 2147));
this.server.StartUp();
this.buttonStart.Enabled = false;
this.buttonStop.Enabled = true;
this.buttonSend.Enabled = true;
MessageBox.Show("Server Started");
}
void server_CloseConnectionEvent(AbstractTcpSocketClientHandler handler)
{
MessageBox.Show(string.Format("A client is disconnected from the server"), "Socket Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
void server_ConnectionEvent(AbstractTcpSocketClientHandler handler)
{
MessageBox.Show(string.Format("A client is connected to the server"), "Socket Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
void server_ReceiveMessageEvent(SocketServerLib.SocketHandler.AbstractTcpSocketClientHandler handler, SocketServerLib.Message.AbstractMessage message)
{
BasicMessage receivedMessage = (BasicMessage)message;
byte[] buffer = receivedMessage.GetBuffer();
if (buffer.Length > 1000)
{
MessageBox.Show(string.Format("Received a long message of {0} bytes", receivedMessage.MessageLength), "Socket Server",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string s = System.Text.ASCIIEncoding.Unicode.GetString(buffer);
this.SetReceivedText(s);
}
private void buttonStop_Click(object sender, EventArgs e)
{
this.server.Shutdown();
this.server.Dispose();
this.server = null;
this.buttonStart.Enabled = true;
this.buttonStop.Enabled = false;
this.buttonStop.Enabled = false;
MessageBox.Show("Server Stopped");
}
private void SetReceivedText(string text)
{
if (this.textBoxReceived.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetReceivedText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBoxReceived.Text = text;
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
ClientInfo[] clientList = this.server.GetClientList();
if (clientList.Length == 0)
{
MessageBox.Show("The client is not connected", "Socket Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
AbstractTcpSocketClientHandler clientHandler = clientList[0].TcpSocketClientHandler;
string s = this.textBoxSend.Text;
byte[] buffer = System.Text.ASCIIEncoding.Unicode.GetBytes(s);
BasicMessage message = new BasicMessage(this.serverGuid, buffer);
clientHandler.SendAsync(message);
}
}
}
The following is the nodejs client code.
var sys = require("sys"),
net = require("net");
var client = net.createConnection(2147);
client.setEncoding("UTF8");
client.addListener("connect", function() {
sys.puts("Client connected.");
// close connection after 2sec
setTimeout(function() {
sys.puts("Sent to server: close");
client.write("close", "UTF8");
}, 2000);
});
client.addListener("data", function(data) {
sys.puts("Response from server: " + data);
if (data == "close") client.end();
});
client.addListener("close", function(data) {
sys.puts("Disconnected from server");
});
I am able to solve the issue. This is just a overlook issue. In server code , I am using lan address assigned to my machine , but in client side , I am using 127.0.0.1 . when I changed the both to same value , I amnot getting econnrefused error.
Now I am able to send and receive data. However I am getting ECONNRESET error very frequently. any leads?

TCPIP connection in c# and data sending/receiving in another threads

I have a problem with my TCPIP connection Form programm.
I have a code, where I'm trying to send and receive some data from server.
The main problem of my app is how to reconcile some threads:
myListenThread - to listening data from server
myReadStreamThread - to read data from server
System.Threading.Thread - main thread eg. to write data to server
captureThread - to do another things like capturing images from camera
Part of my code:
private void buttonConnect_Click(object sender, EventArgs e)
{
try
{
Connect();
Connected = true;
this.myListenThread = new Thread(new ThreadStart(Listen));
this.myListenThread.Start();
}
catch
{
MessageBox.Show("Invalid host! Try again.");
}
}
private void Listen()
{
this.myReadStreamThread = new Thread(new ThreadStart(ReadStream));
this.myReadStreamThread.Start();
while (Connected)
{
if (!myReadClient.Connected)
{
Connect();
}
}
}
private void Connect()
{
IPAddress IP = IPAddress.Parse(textboxIP.Text);
int PORT = Convert.ToInt32(textboxPORT.Text);
this.myReadClient = new TcpClient();
this.myReadClient.Connect(IP, PORT);//SOMETIMES HERE'S AN ERROR
this.myStream = this.myReadClient.GetStream();
Properties.Settings.Default.IP = Convert.ToString(IP);
Properties.Settings.Default.PORT = Convert.ToString(PORT);
Properties.Settings.Default.Save();
}
private void ReadStream()
{
while (true)
{
try
{
this.myReadBuffer = new byte[this.myReadClient.ReceiveBufferSize];
this.myBufferSize = myStream.Read(myReadBuffer, 0, this.myReadClient.ReceiveBufferSize);
if (myBufferSize != 0)
{
this.myString = Encoding.ASCII.GetString(myReadBuffer);
//myDelegate myDel;
//myDel = new myDelegate(Print);
//richtextboxRead.Invoke(myDel);
}
}
catch
{
break;
}
}
}
All is working correct when I'm connecting to server, but when I want to send some string the problem appears because of threads.
I decided to send string, by clicking Button3 and waiting until I receive string "1" from server using while loop:
private void button3_Click(object sender, EventArgs e)
{
this.captureThread = new Thread(new ThreadStart(() => this.newGame()));
this.captureThread.Start();
}
private bool newGame()
{
string command = "12345abc";
if (Connected)
{
WriteStream(command);
}
while (myBufferSize == 0 && myString !="1") { }
Thread.Sleep(2000);
...//doing other things
}
private void WriteStream(string command)
{
Connect();
this.myWriteBuffer = Encoding.ASCII.GetBytes(command);
this.myStream.Write(this.myWriteBuffer, 0, command.Length);
}
And the problem with connection and data send/receive problem appears, when it should write my string "command" - it doesn't react. MyBufferSize is always 0 and myString is always null. Sometimes an Error about connection appears when I click Button3 (assigned in code). I think it is because in captureThread I can't see any data from another threads. How to solve it?

Issue with opening and closing serial port

I am currently working on C# application which requires to read serial port. In UI, there is a ON/OFF button which enables user click on it to start and stop reading data from serial port. If I continuously click on the button on and off. It threw an exception - Access to COM3 is denied or even said "The device is not connected". Can anyone suggest a better way to implement the serial port function which is able to resolve the situation as described above? Here is the code I use:
**// Start reading data from serial port**
public override void StartReading(string portname)
{
try
{
int k = int.Parse(portname.Replace("COM", ""));
if (startThread != null)
{
startThread.Abort();
startThread = null;
}
startThread = new Thread(new ThreadStart(delegate
{
isActive = true;
try
{
using (SerialPort sp = new SerialPort(portname))
{
if (!isActive)
{
DisposeBT(sp);
return;
}
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
if (!isActive)
{
DisposeBT(sp);
return;
}
if (!isActive)
{
DisposeBT(sp);
return;
}
else
{
Thread.Sleep(6500);
try
{
if (sp != null && !sp.IsOpen)
{
sp.Open();
}
}
catch (Exception ex)
{
Logger.Warn("Failed to open the serial port for HRM once. Try it again.");
Logger.Error(ex);
////////////////////// new added below
if(sp !=null && sp.IsOpen)
{
sp.Dispose();
}
Thread.Sleep(6500);
if (IsPortAvailable(k))
{
try
{
if (sp != null && !sp.IsOpen)
{
sp.Open();
}
}
catch (Exception ex1)
{
////////////////////// new added below
if (sp != null && sp.IsOpen)
{
sp.Dispose();
}
Logger.Warn("Failed to open the serial for HRM twice.");
Logger.Error(ex1);
// return;
}
}
}
}
while (true)
{
if (!isActive)
{
DisposeBT(sp);
break;
}
}
if (!isActive)
{
DisposeBT(sp);
return;
}
DisposeBT(sp);
}
}
catch (Exception ex)
{
Logger.Warn("Exception thrown for HRM.");
Logger.Error(ex);
}
}));
startThread.IsBackground = true;
startThread.Priority = ThreadPriority.Highest;
startThread.Start();
}
catch (Exception ex)
{
Logger.Warn("Failed to start reading for HRM02I3A1 bluetooth device.");
Logger.Error(ex);
}
}
// Stop reading data from serial port
public override void StopReading()
{
try
{
isActive = false;
}
catch { }
}
// event handler for the serial port to read data from sp.
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (isActive)// && startThread.IsAlive
{
SerialPort sp1 = (SerialPort)sender;
try
{
sp1.Read(data, 0, 8);
decoder.Decode(data);
}
catch(Exception ex)
{
Logger.Warn("------data received from Serial Port error for HRM-------");
Logger.Error(ex);
};
}
}
first make background worker thread that accept the cancel event.
in the DoWork method you can write something like that
void DoWork{
// init com port
while(no body cancelled the background worker){
// if there any waiting data receive and process it. do not use event handlers
}
// close the serial port so you can open it again later.
}
Also if you want to cancel the background work it would be a piece of cake
// send cancel command.
// wait till it is canceled.
Try adding startThread.Join() directly after the call to startThread.Abort().
Take a look at the msdn documentation on Thread.Abort and perhaps you also should check what join does.

disconnect/close a client [duplicate]

This question already has an answer here:
C# -- TcpListener.Start() causing SocketException with message "Only one usage of each socket address"
(1 answer)
Closed 2 years ago.
I have a simple client-server application which works like this: the server is always listening (in a separate thread) for a client connection (which sends the name of process that it wants the server to kill).
Here is the server:
private void btnStart_Click(object sender, EventArgs e)
{
_port = int.Parse(comboBoxPorts.SelectedItem.ToString());
_tcpListener = new TcpListener(_ipAddress, _port);
_keepRunning = true;
_listenerThread = new Thread(Listen);
HandleListenerThreadStartListenEvent += HandleListenerThreadStartedEventMethod;
ListenerThreadStartedEvent += HandleListenerThreadStartListenEvent;
_listenerThread.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (_tcpListener != null)
{
_keepRunning = false;
if (_tcpListener.Server.Connected)
{
_tcpListener.Server.Disconnect(true);
}
_tcpListener.Stop();
}
labelServerStatus.Text = "Server is stopped";
comboBoxPorts.Enabled = true;
btnStart.Enabled = true;
btnStop.Enabled = false;
}
private void Listen()
{
try
{
_tcpListener.Start();
OnListenerThreadStartListenEvent(); // just update the GUI
}
catch(Exception e)
{
MessageBox.Show("Port " + _port + " is NOT available." + Environment.NewLine +
"Please choose another one: " + e.Message);
return;
}
_keepRunning = true;
string ballonMessage = "Socket Server Running at " + _ipAddress + ", port: " + _port;
notifyIcon1.ShowBalloonTip(2000, "Simplex Listener", ballonMessage, ToolTipIcon.Info);
while (_keepRunning)
{
try
{
#region using AcceptSocket()
_clientSocket = _tcpListener.AcceptSocket();
string checkString = string.Empty;
IPAddress ipOfClient = ((IPEndPoint) _clientSocket.LocalEndPoint).Address;
notifyIcon1.ShowBalloonTip(2000, "Simplex Listener", "New client has connected from ip " + ipOfClient, ToolTipIcon.Info);
byte[] buffer = new byte[SIZE_OF_BUFFER];
int bytesReceived = _clientSocket.Receive(buffer);
// Concatenate chars as bytes to a received string.
for (int i = 0; i < bytesReceived; i++)
checkString += Convert.ToChar(buffer[i]);
//..... getting the name of process and kill it (and than open it...
RestartProcess(nameOfProcess, windowName, pathToExeFile);
// Client is waiting to know operation is complete- so send him some char...
ASCIIEncoding encoder = new ASCIIEncoding();
_clientSocket.Send(encoder.GetBytes("v"));
_clientSocket.Disconnect(true);
_clientSocket.Close();
#endregion
}
catch (Exception )
{
}
}
}
The client side:
public void RestartTheSoftwareInServerComputer(string ipOfServer, int portNumber)
{
TcpClient client = new TcpClient();
if (_serverEndPoint == null)
{
_serverEndPoint = new IPEndPoint(IPAddress.Parse(ipOfServer), portNumber);
}
client.Connect(_serverEndPoint);
// Send the command to the server:
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("....detailsOfProcess....");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
// Now, wait for the server's response [which means the process had been restart].
NetworkStream stream = client.GetStream();
byte[] bytes = new byte[5];
stream.Read(bytes, 0, 5);
string response = Encoding.UTF8.GetString(bytes, 0, 1);
if (response.Equals("x"))
{
throw new Exception("Failed to restart X software.");
}
stream.Close();
client.Close();
}
When I stop and restart the server (when no client had connected), then everything is OK.
The problem is when the server got some client connected, and is restarted, then the client has disconnected and the server needs to be restarted. When we hit the "START SERVER" again it will get the exception:
Only one usage of each socket address (protocol/network address/port)
is normally permitted.
How should I close the port?
When you exit your server, you should call _tcpListener.Stop() to close the main socket that the server is listening on.
Edit: You could also try to call _listenerThread.Join() in your stop button click, to wait for the listener thread to finish, before starting the next one.
private void btnStop_Click(object sender, EventArgs e)
{
if (_tcpListener != null)
{
_keepRunning = false;
if (_tcpListener.Server.Connected)
{
_tcpListener.Server.Disconnect(true);
_tcpListener.Stop();
if (_clientSocket != null)
{
_clientSocket.Close();
_clientSocket = null;
}
_listenerThread.Join();
}
}
labelServerStatus.Text = "Server is stopped";
comboBoxPorts.Enabled = true;
btnStart.Enabled = true;
btnStop.Enabled = false;
}
EDIT 2:
here is a windows form that does similar to your server. I didn't need a client, just use "telnet localhost 49152" from a command prompt to 'pretend' to be the client connecting.
public partial class Form1 : Form
{
private TcpListener _tcpListener;
private bool _keepRunning;
private Thread _listenerThread;
private Socket _clientSocket;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var address = IPAddress.Parse("127.0.0.1");
_tcpListener = new TcpListener(address, 49152);
_keepRunning = true;
_listenerThread = new Thread(Listen);
_listenerThread.Start();
button1.Enabled = false;
button2.Enabled = true;
}
private void Listen()
{
try
{
_tcpListener.Start();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
_keepRunning = true;
while (_keepRunning)
{
try
{
_clientSocket = _tcpListener.AcceptSocket();
var buffer = new byte[8192];
var bytesReceived = _clientSocket.Receive(buffer);
var checkString = String.Empty;
if (_keepRunning)
{
// bytesReceived can be 0 if the remote socket disconnected
if (bytesReceived > 0)
{
checkString = Encoding.ASCII.GetString(buffer, 0, bytesReceived);
// Client is waiting to know operation is complete- so send him some char...
var encoder = new ASCIIEncoding();
_clientSocket.Send(encoder.GetBytes("v"));
}
if (_clientSocket.Connected) _clientSocket.Disconnect(true);
}
_clientSocket.Close();
}
catch (Exception ex)
{
// really should do something with these exceptions
}
}
}
private void button2_Click(object sender, EventArgs e)
{
if (_tcpListener != null)
{
_keepRunning = false;
if (_tcpListener.Server.Connected)
{
_tcpListener.Server.Disconnect(true);
}
_tcpListener.Stop();
if (_clientSocket != null)
{
_clientSocket.Close();
_clientSocket = null;
}
_listenerThread.Join();
}
button1.Enabled = true;
button2.Enabled = false;
}
}
There are a lot of problems with this code, e.g. sharing variables across threads etc. but on my machine the Join doesn't seem to block for any length of time. The problem with _keepRunning is that on certain systems it's possible for one thread to not see the change from true to false, because it gets optimised or cached. You should really use some form of thread synchronisation, make it volatile, or wrap it in a lock etc. I'd suggest you have a read here about this. I'd also suggest you have a read up on Sockets too, or if as other commenters have mentioned, if you aren't interested in learning about all the idiosyncrasies of sockets and threading, perhaps you should look for a higher level library that hides it all?

Categories