ReadAsync - thread exited with code 259 - c#

I have problems with bluetooth connection. It is endless connection and after several seconds it is always hangs up on ReadAsync with information:
The thread 0x19c has exited with code 259 (0x103).
The program '[5612] TaskHost.exe' has exited with code 0 (0x0).
After this - connection is still valid with device (I see connection diode on device), but there is no chance to:
1) Connect again to device (connection is still present)
2) Receive any data from socket/connection
It is allways hanging here:
returnedBuffer =
await
socket.InputStream.ReadAsync(buffer.AsBuffer(), (uint)buffer.Length,
InputStreamOptions.Partial);
Modyfied code is from 32feet sample:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
var bdp = new BluetoothDevicePicker();
PeerInformation pi = await bdp.PickDeviceAsync();
if (pi != null)
{
var hn = new HostName(pi.HostName.RawName);
// do something with the device
ReadThread(hn);
}
}
private async void ReadThread(object host)
{
reading = true;
var socket = new StreamSocket();
socket.Control.KeepAlive = true;
socket.Control.NoDelay = false;
//socket.Control.QualityOfService = SocketQualityOfService.LowLatency;
IAsyncAction a = StreamSocketExtensions.ConnectAsync(socket, (HostName)host, RfcommServiceId.SerialPort);
await a;
var buffer = new byte[2048];
while (reading)
{
IBuffer returnedBuffer = null;
try
{
returnedBuffer =
await
socket.InputStream.ReadAsync(buffer.AsBuffer(), (uint)buffer.Length,
InputStreamOptions.Partial);
if (returnedBuffer != null)
{
string s = PrintByteArray(returnedBuffer.ToArray(), (int)returnedBuffer.Length);
if (!string.IsNullOrEmpty(s))
{
Dispatcher.BeginInvoke(new Action<string>(InsertMessage), s);
}
}
}
catch
{
}
}
socket.Dispose();
}

Related

TcpClient hangs after connection to remote host & application freezes c#

I am trying to establish a connection to a remote host via IP address and Port number. The connection does get established (even verified using cmd netstat) however when I try to close the connection in code:
clientConnection.Client.Close();
clientConnection.Client.Dispose();
clientConnection.Close();
The program crashes because the socket does not have any available data to be read from the client stream. In my windows application (client) I have a button which I click to call the ConnectToFalcon method and that calls the ReadStream method. Please let me know where have I been going wrong.
public void readStream(object argument)
{
clientConnection = (TcpClient)argument;
//TcpClient client = new TcpClient();
DateTime start_time = DateTime.Now;
TimeSpan delay = new TimeSpan(0, 0, 10);
while (clientConnection.Available == 0)
{
Application.DoEvents();
if (DateTime.Now.Subtract(start_time) > delay)
break;
}
if ((clientConnection != null) && (clientConnection.Available > 0))
{
var message = new byte[1];
Array.Resize(ref message, clientConnection.Available);
//remove below two lines and if-statement block if program crashes
clientConnection.Client.ReceiveTimeout = 20000; //Timeout after 20 seconds
clientConnection.SendTimeout = 20000;
if (clientConnection.Client.ReceiveTimeout <= 20000 || clientConnection.SendTimeout == 20000)
{
clientConnection.Client.Receive(message);
string testResult = System.Text.Encoding.Default.GetString(message);
}
else
{
MessageBox.Show("Time expired before read operation completed.");
}
}
else if (((clientConnection == null) && (clientConnection.Available <= 0)) || (clientConnection.Connected == false))
{
clientConnection.Close();
MessageBox.Show("Closing client connection due to insufficient amount of data available to be read");
}
//clientConnection.Client.Close();
//clientConnection.Client.Dispose();
//clientConnection.Close();
}}
public void ConnectToFalcon(string IPaddress, int port)
{
clientConnection = new TcpClient();
//var result = clientConnection.BeginConnect(IPaddress, port, new AsyncCallback(callback), clientConnection);
var result = clientConnection.BeginConnect(IPaddress, port, null, null);
var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));
if (success == false)
{
MessageBox.Show("Failed to connect");
}
else
{
MessageBox.Show("Client connected...");
while (true)
{
Thread t = new Thread(readStream);
t.Start(clientConnection); //A new thread is spawned
//t.Start();
}
}
}
According to #Luaan, You must call EndConnect on the IAsyncResult in the callback function in order to acknowledge the client request.`
public void callback(IAsyncResult ar)
{
this.clientConnection.EndConnect(ar);
}
var result = clientConnection.BeginConnect(ip, port, new AsyncCallback(callback), clientConnection);

Asynchronous problems writing to server

The application is for the Windows 8 Mobile platform, and it tends to crash when I send some data to the server at a point during it's life cycle.
await writer.StoreAsync();
An exception of type 'System.Exception' occurred in mscorlib.ni.dll but was not handled in user code
Additional information: An established connection was aborted by the software in your host machine. (Exception from HRESULT: 0x80072745)
Even if I put it in a try catch, I can't throw the exception, since it feels it still closes the program.
When a button is pressed, it sends a message to the server;
private void button_Click(object sender, RoutedEventArgs e)
{
Task t = new Task(TalkToServer);
if (t.IsCompleted != t.IsCompleted)
{
}
else
{
t.RunSynchronously();
}
}
So if I press the button it will start a new task. If the task is completed, then run the task, else if it isn't then do not.
private async void TalkToServer()
{
if (clientSocket == null)
return;
DataWriter writer = new DataWriter(clientSocket.OutputStream);
MessageData md = new MessageData();
md.MyUser = new User("us", "ps");
md.MyType = MessageData.mType.REQUESTMEMBERS;
string output = JsonConvert.SerializeObject(md);
writer.WriteString(output);
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
}
This is the method call that sends the data, but await writer.StoreAsync();
tends to crash the program. This code is used in the beggining of a program on a seperate page and it works, but it dues to
EDIT ---- after looking at the further reading that user method man had presented, I changed the implementation to :
private async void button_Click(object sender, RoutedEventArgs e)
{
await sendInfo();
}
private async Task sendInfo()
{
if (clientSocket == null)
return;
DataWriter writer = new DataWriter(clientSocket.OutputStream);
MessageData md = new MessageData();
md.MyUser = new User("us", "ps");
md.MyType = MessageData.mType.REQUESTMEMBERS;
string output = JsonConvert.SerializeObject(md);
writer.WriteString(output);
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
return ;
}
Also the title was changed

Where must i throw an exception to prevent endless waiting in Task

I have a hardware device connected to my PC over serial port, when i signal something to it, it signals back that "Hi, here I am!" and then it is successfully detected the port on which it is connected. I wrote a Task in C# that waits for the response coming from the hardware device, but if it is not connected, then this task is waiting forever.. Where can i throw an exception to prevent this endless waiting?
My code:
public static Task<string> GetDevicePortName()
{
// Get all available serial ports on system.
var ports = SerialPort.GetPortNames();
var serialPort = new SerialPort();
serialPort.BaudRate = Constants.DeviceConstants.BaudRate;
serialPort.Parity = Constants.DeviceConstants.SerialPortParity;
serialPort.StopBits = Constants.DeviceConstants.SerialPortStopBits;
serialPort.WriteTimeout = Constants.DeviceConstants.WriteTimeoutInMilliseconds;
var taskCompletionSource = new TaskCompletionSource<string>();
serialPort.DataReceived += (s, e) =>
{
var dataIn = (byte)serialPort.ReadByte();
var receivedCharacter = Convert.ToChar(dataIn);
if (receivedCharacter == Constants.DeviceConstants.SignalYes)
{
serialPort.Dispose();
taskCompletionSource.SetResult(serialPort.PortName);
}
};
foreach (var port in ports)
{
serialPort.PortName = port;
try
{
serialPort.Open();
serialPort.Write(Constants.DeviceConstants.SignalDeviceDetect);
}
catch (IOException e) { }
}
return taskCompletionSource.Task;
}
You can create a "Custom timeout" combining Task.WhenAny with Task.Delay:
public async Task GetDevicePortNameAsync()
{
var cts = new CancellationTokenSource();
var timeOutTask = Task.Delay(5000, cts.Token);
var deviceNameTask = GetDevicePortName(cts.Token);
var finishedTask = await Task.WhenAny(timeOut, deviceNameTask);
if (finishedTask == timeOutTask)
{
// You've timed-out
}
// If you get here, the deviceName is available.
}
Note this won't cancel the underlying registration to SerialPort.
Edit:
#KDecker adds an idea to pass a CancellationToken which can be monitored in case we've already timed out before returning the TaskCompletionSource.Task. It would look like this:
public static Task<string> GetDevicePortName(CancellationToken cancellationToken)
{
// Get all available serial ports on system.
var ports = SerialPort.GetPortNames();
var serialPort = new SerialPort();
serialPort.BaudRate = Constants.DeviceConstants.BaudRate;
serialPort.Parity = Constants.DeviceConstants.SerialPortParity;
serialPort.StopBits = Constants.DeviceConstants.SerialPortStopBits;
serialPort.WriteTimeout = Constants.DeviceConstants.WriteTimeoutInMilliseconds;
var taskCompletionSource = new TaskCompletionSource<string>();
serialPort.DataReceived += (s, e) =>
{
var dataIn = (byte)serialPort.ReadByte();
var receivedCharacter = Convert.ToChar(dataIn);
if (receivedCharacter == Constants.DeviceConstants.SignalYes)
{
serialPort.Dispose();
taskCompletionSource.SetResult(serialPort.PortName);
}
};
foreach (var port in ports)
{
if (cancellationToken.IsCancellationRequested)
{
// Unregister from serialPort, and clean up whatever needs to be cleaned
taskCompletionSource.SetResult(null);
break;
}
serialPort.PortName = port;
try
{
serialPort.Open();
serialPort.Write(Constants.DeviceConstants.SignalDeviceDetect);
}
catch (IOException e) { }
finally
{
serialPort.Dispose();
}
}
return taskCompletionSource.Task;
}

Label won't change color until after code is finished executing

It's a lot of irrelevant code to look through.. but pretty much it sends a packet and listens for a packet in return
if i comment the part out where it calls the ReceiveAuthPacket() method at the end of sending a packet, it will work and the label will turn blue.. but otherwise it will never activate turning the label blue and will instead turn the label red or green (depending on the returned packet).
basically im just using the label as an indicator of the status.. and no matter what i try i can't get it to turn blue because it seems to be waiting for all the code to be finished executing and it just won't work..
i even tried using data triggers in WPF and it still won't work.
any work arounds? i just don't get it..
private readonly UdpMessageAuthentication _msgAuth;
private void Button_Authenticate_OnClick(object sender, RoutedEventArgs e)
{
Label_Authentication.Content = "Attempting Authentication";
Label_Authentication.Foreground = new SolidColorBrush(Colors.Blue);
_msgAuth.SendAuthPacket(IPAddress.Parse(TextBox_IP.Text), TextBox_ClientID.Text);
}
public void SendAuthPacket(IPAddress ip, string userID)
{
_ip = ip;
_userID = userID;
if (_udpClient.Client == null)
_udpClient = new UdpClient();
//GSISClockRegRequest,<Client Id>,,1
string msg = string.Format("GSISClockRegRequest,{0},,1", _userID);
byte[] sendBytes = Encoding.ASCII.GetBytes(msg);
bool sent = false;
try
{
_label.Content = "Attempting Authentication";
_label.Foreground = new SolidColorBrush(Colors.Blue);
while (_label.Content != "Attempting Authentication")
{
//loop
}
_udpClient.Connect(_ip, 5001);
_udpClient.Send(sendBytes, sendBytes.Length);
Console.WriteLine("Sending {0} bytes. Message: {1}", sendBytes.Length, msg);
sent = true;
}
catch (Exception)
{
Console.WriteLine("UDP Auth Packet Failed to Send");
}
_udpClient.Close();
if (sent)
ReceiveAuthPacket(); //IF I COMMENT THIS OUT IT'LL WORK
}
private void ReceiveAuthPacket()
{
IPEndPoint e = new IPEndPoint(IPAddress.Any, 5001);
UdpClient u = new UdpClient(e);
u.Client.ReceiveTimeout = 3000;
Console.WriteLine("Listening for Messages: ");
try
{
Byte[] receiveBytes = u.Receive(ref e);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("Received: {0}", receiveString);
string errMsg = "";
if (AuthMessageParser.ParseMessage(receiveString, ref errMsg))
{
_label.Content = "Authentication Successful!";
_label.Foreground = new SolidColorBrush(Colors.Green);
}
else
{
_label.Content = "Authentication Unsuccessful: " + errMsg;
_label.Foreground = new SolidColorBrush(Colors.Red);
}
}
catch (Exception)
{
_label.Content = "Authentication Unsuccessful";
_label.Foreground = new SolidColorBrush(Colors.Red);
Console.WriteLine("UDP Auth Packet was NOT Received.");
}
u.Close();
}
Your UI thread is blocked by calls to things like _udpClient.Connect() and _udpClient.Send() (and the receives, too)
A workaround would be to leverage the task parallel library and perform communications asynchronously to avoid blocking the UI thread.
It will manage threads for you as long as you define tasks properly. Holler if you need an example.
protected void SomeButton_Click(Object sender, EventArgs e)
{
// Task off the work and do not wait, no blocking here.
Task.Run(PerformConnection);
}
private async Task PerformConnection()
{
// This method acts the way a thread should. We await the result of async comms.
// This will not block the UI but also may or may not run on its own thread.
// You don't need to care about the threading much.
var conn = await ListenerOrSomething.AwaitConnectionsAsync( /* ... */ );
// Now you have your result because it awaited.
using(var newClient = conn.Client())
{
var buffer = new byte[];
var recv = await newClient.ReceiveAsyncOrSomething(out buffer);
// Data received is not zero, process it or return
if(recv > 0)
newClient.Response = await ProcessRequest(buffer);
else
return;
}
}

Why does C# thread die?

This is my 1st C# project so I may be doing something obviously improper in the code below.
I am using .NET, WinForms (I think), and this is a desktop application until I get the bugs out.
UpdateGui() uses Invoke((MethodInvoker)delegate to update various GUI controls based on received serial data and
sends a GetStatus() command out the serial port 4 times a second.
Thread Read() reads the response from serial port whenever it arrives which should be near immediate.
SerialPortFixer is a SerialPort IOException Workaround in C# I found at
http://zachsaw.blogspot.com/2010/07/serialport-ioexception-workaround-in-c.html.
After one or both threads die I'll see something like
The thread 0x1288 has exited with code 0 (0x0).
in the debug code output.
Why do UpdateGui() and/or Read() eventually die?
public partial class UpdateStatus : Form
{
private readonly byte[] Command = new byte[32];
private readonly byte[] Status = new byte[32];
readonly Thread readThread;
private static readonly Mutex commandMutex = new Mutex();
private static readonly Mutex statusMutex = new Mutex();
...
public UpdateStatus()
{
InitializeComponent();
SerialPortFixer.Execute("COM2");
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
try
{
serialPort1.Open();
}
catch (Exception e)
{
labelWarning.Text = LOST_COMMUNICATIONS + e;
labelStatus.Text = LOST_COMMUNICATIONS + e;
labelWarning.Visible = true;
}
readThread = new Thread(Read);
readThread.Start();
new Timer(UpdateGui, null, 0, 250);
}
static void ProcessStatus(byte[] status)
{
Status.State = (State) status[4];
Status.Speed = status[6]; // MSB
Status.Speed *= 256;
Status.Speed += status[5];
var Speed = Status.Speed/GEAR_RATIO;
Status.Speed = (int) Speed;
...
}
public void Read()
{
while (serialPort1 != null)
{
try
{
serialPort1.Read(Status, 0, 1);
if (Status[0] != StartCharacter[0]) continue;
serialPort1.Read(Status, 1, 1);
if (Status[1] != StartCharacter[1]) continue;
serialPort1.Read(Status, 2, 1);
if (Status[2] != (int)Command.GetStatus) continue;
serialPort1.Read(Status, 3, 1);
...
statusMutex.WaitOne();
ProcessStatus(Status);
Status.update = true;
statusMutex.ReleaseMutex();
}
catch (Exception e)
{
Console.WriteLine(#"ERROR! Read() " + e);
}
}
}
public void GetStatus()
{
const int parameterLength = 0; // For GetStatus
statusMutex.WaitOne();
Status.update = false;
statusMutex.ReleaseMutex();
commandMutex.WaitOne();
if (!SendCommand(Command.GetStatus, parameterLength))
{
Console.WriteLine(#"ERROR! SendCommand(GetStatus)");
}
commandMutex.ReleaseMutex();
}
private void UpdateGui(object x)
{
try
{
Invoke((MethodInvoker)delegate
{
Text = DateTime.Now.ToLongTimeString();
statusMutex.WaitOne();
if (Status.update)
{
if (Status.Speed > progressBarSpeed.Maximum)
{
Status.Speed = progressBarSpeed.Maximum;
}
progressBarSpeed.Value = Status.Speed;
labelSpeed.Text = Status.Speed + RPM;
...
}
else
{
labelWarning.Text = LOST_COMMUNICATIONS;
labelStatus.Text = LOST_COMMUNICATIONS;
labelWarning.Visible = true;
}
statusMutex.ReleaseMutex();
GetStatus();
});
}
catch (Exception e)
{
Console.WriteLine(#"ERROR! UpdateGui() " + e);
}
}
}
A thread will terminate when there's no more code to execute, or more specifically when the method you specify when you create thread returns.
Maybe serialport1 becomes null?
As for the update timer, there is a special purpose windows forms timer that runs periodically that doesn't require you to use Invoke. It's the right tool for the job

Categories

Resources