I've been trying to build a packet sniffer using SharpPcap and PacketDotNet.
This is my code so far:
public static void SniffConnection()
{
var packets = new List<RawCapture>();
var devices = CaptureDeviceList.Instance;
PcapDevice device = null;
foreach (var dev in devices)
{
if (((LibPcapLiveDevice)dev).Interface.FriendlyName.Equals("Wi-Fi 3"))
{
device = (LibPcapLiveDevice)dev;
break;
}
}
try
{
//Open the device for capturing
device.Open(DeviceMode.Promiscuous);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return;
}
//Register our handler function to the 'packet arrival' event
device.OnPacketArrival += (sender, packets_storage) => PacketArrivalHandler(sender, ref packets);
Console.WriteLine("sniffing...");
try
{
device.Capture();
}
catch (System.AccessViolationException e)
{
Console.WriteLine(e);
}
catch (Exception e)
{
Console.WriteLine(e);
}
device.Close();
Console.ReadLine();
}
public static void PacketArrivalHandler(object sender, ref List<RawCapture> packets)
{
var dev = (WinPcapDevice)sender;
RawCapture p = dev.GetNextPacket();
if (p != null)
{
var raw_packet = Packet.ParsePacket(p.LinkLayerType, p.Data); // split the packet into layers to check the data in layers is valid
var tcpPacket = (TcpPacket)raw_packet.Extract(typeof(TcpPacket));
var ipPacket = (IpPacket)raw_packet.Extract(typeof(IpPacket));
packets.Add(p);
}
}
After a few packets are captured, the Capture function throws an exception, usually something about memory. (Access Violation, Out of Memory, Overflow)
Any idea what's causing this and how to solve this?
(when Out of Memory or Overflow exceptions are thrown, it says it's something in SharpPcap.LibPcap.PcapDevice.MarshalRawPacket function, but when the Access Violation is thrown, it says it's happenning in a dll thats not even related to my code directly)
Related
Error Java.Net.SocketException: Binding socket to network 626 failed: ENONET (Machine is not on the network)
Xamarin app: this method is written for android.
I am getting this error, it is not reported every time, it is difficult for me to capture it in test environments.
Why is this error, what is the explanation?
what can be done to have better control in this method?
There is a similar question asked some time ago, but it does not the same operation that I do here, and it is not solved.
public static void BindSocketToWifi(Socket socket)
{
try
{
ConnectivityManager connectivityManager = (ConnectivityManager)Android.App.Application.Context.GetSystemService(Context.ConnectivityService);
NetworkInfo wifiInfo = null;
var networks = connectivityManager.GetAllNetworks();
foreach (var net in networks)
{
wifiInfo = connectivityManager.GetNetworkInfo(net);
if (wifiInfo.Type == ConnectivityType.Wifi)
{
try
{
net.BindSocket((Socket)socket);
}
catch (Exception ex)
{
Crashes.TrackError(ex);
throw ex;
}
break;
}
}
}
catch (Exception e)
{
Crashes.TrackError(e);
throw e;
}
}
Scenario:
I am building an Android app using Xamarin.Forms that will be deployed to a group of devices. All but one of the devices will be doing some data collection, and the remaining device will be the "hub" to aggregate all of the data and do some reporting. I am using Bluetooth for the device-to-device communication. The 'hub', labelled the master, acts as the client, and all of the collectors act as the server. I have a prototype working with a single server and client...almost.
Occasionally the client/master will be unable to read from the server/collector. I am struggling to find the reason for why this is and would appreciate any help.
Symptoms:
The client's call to .Read() from the InputStream will occasionally block indefinitely, even though the server has written to the output stream. I've added a timeout to this call to prevent the app from getting stuck entirely.
This happens intermittently, but I've found some pattern to when it works and when it doesn't
It seems to be related to the 'server' app, and not the client. The client can remain open, running, and initiate the request to connect to the server as often as needed.
It always works the first time the 'server' app is launched and connected to. It ususally works the second time. By the third connection, .Read() will consistently block/timeout. Closing and reopening the app on the server "cleans the slate" so to speak and it will work again.
Once it starts failing, it seems to be 'stuck' in a failed state.
Removing the app from the foreground (but not closing/killing it) seems to correct the faulted state, and the connection/read will happen successfully as long as the app/UI remains in the background. Once restored to the foreground, it starts failing again.
Code:
All of the bluetooth handling is done by a single class/service that I'm injecting using Xamarin.Forms DependencyService. All of the devices will, on startup (via the constructor of this class), loop indefinitely on a background thread, waiting for connections and repeating. Much of this bluetooth code is based on the Bluetooth Chat example, as well as some other online resources I've found (some android native/java, some Xamarin/C#)
The master will, on demand (triggered by press of a button in the UI), attempt to connect to any collectors (via bonded bluetooth devices) and read data from them. There is also a simple UI component which essentially serves as a console log.
Here is the service class in its entirety.
public class GameDataSyncService : IGameDataSyncService
{
private const string UUID = "8e99f5f1-4a07-4268-9686-3a288326e0a2";
private static Task acceptLoopTask;
private static Task syncDataTask;
private static readonly object locker = new object();
private static bool running = false;
public event EventHandler<DataSyncMessage> MessageBroadcast;
public GameDataSyncService()
{
// Every device will listen and accept incoming connections. The master will make the connections.
lock (locker)
{
if (acceptLoopTask == null)
{
acceptLoopTask = Task.Factory.StartNew(AcceptLoopWorker, TaskCreationOptions.LongRunning);
}
}
}
public void SyncData()
{
lock (locker)
{
if (running)
{
BroadcastMessage("Previous data sync is still running.", DataSyncMessageType.Warning);
return;
}
else
{
running = true;
syncDataTask = Task.Factory.StartNew(SyncDataWorker);
}
}
}
private void BroadcastMessage(string message, DataSyncMessageType type = DataSyncMessageType.Info)
{
MessageBroadcast?.Invoke(this, new DataSyncMessage { Text = message, Type = type });
}
private async Task AcceptLoopWorker()
{
int count = 0;
while (true)
{
BluetoothServerSocket serverSocket = null;
BluetoothSocket clientSocket = null;
try
{
BroadcastMessage($"Listening for incoming connection...", DataSyncMessageType.Debug);
serverSocket = BluetoothAdapter.DefaultAdapter.ListenUsingRfcommWithServiceRecord(nameof(GameDataSyncService), Java.Util.UUID.FromString(UUID));
clientSocket = serverSocket.Accept(); // This call blocks until a connection is established.
BroadcastMessage($"Connection received from {clientSocket.RemoteDevice.Name}. Sending data...", DataSyncMessageType.Info);
var bytes = Encoding.UTF8.GetBytes($"Hello World - {string.Join(" ", Enumerable.Repeat(Guid.NewGuid(), ++count))}");
await clientSocket.OutputStream.WriteAsync(bytes, 0, bytes.Length);
clientSocket.OutputStream.Flush();
// Give the master some time to close the connection from their end
await Task.Delay(1000*3);
}
catch (Exception ex)
{
BroadcastMessage($"{ex.GetType().FullName}: {ex.Message}", DataSyncMessageType.Debug);
}
finally
{
try { clientSocket?.InputStream?.Close(); } catch { }
try { clientSocket?.InputStream?.Dispose(); } catch { }
try { clientSocket?.OutputStream?.Close(); } catch { }
try { clientSocket?.OutputStream?.Dispose(); } catch { }
try { clientSocket?.Close(); } catch { }
try { clientSocket?.Dispose(); } catch { }
try { serverSocket?.Close(); } catch { }
try { serverSocket?.Dispose(); } catch { }
BroadcastMessage($"Connection closed.", DataSyncMessageType.Debug);
}
}
}
private async Task SyncDataWorker()
{
BroadcastMessage($"Beginning data sync...");
foreach (var bondedDevice in BluetoothAdapter.DefaultAdapter.BondedDevices.OrderBy(d => d.Name))
{
BluetoothSocket clientSocket = null;
try
{
clientSocket = bondedDevice.CreateRfcommSocketToServiceRecord(Java.Util.UUID.FromString(UUID));
BroadcastMessage($"Connecting to {bondedDevice.Name}...");
try
{
clientSocket.Connect();
}
catch
{
BroadcastMessage($"Connection to {bondedDevice.Name} failed.", DataSyncMessageType.Error);
}
while (clientSocket.IsConnected)
{
byte[] buffer = new byte[1024];
var readTask = clientSocket.InputStream.ReadAsync(buffer, 0, buffer.Length);
if (await Task.WhenAny(readTask, Task.Delay(1000)) != readTask)
{
BroadcastMessage($"Read timeout...", DataSyncMessageType.Error);
break;
}
int bytes = readTask.Result;
BroadcastMessage($"Read {bytes} bytes.", DataSyncMessageType.Success);
if (bytes > 0)
{
var text = Encoding.UTF8.GetString(buffer.Take(bytes).ToArray());
BroadcastMessage(text, DataSyncMessageType.Success);
break;
}
}
}
catch (Exception ex)
{
BroadcastMessage($"{ex.GetType().FullName}: {ex.Message}", DataSyncMessageType.Debug);
}
finally
{
try { clientSocket?.InputStream?.Close(); } catch { }
try { clientSocket?.InputStream?.Dispose(); } catch { }
try { clientSocket?.OutputStream?.Close(); } catch { }
try { clientSocket?.OutputStream?.Dispose(); } catch { }
try { clientSocket?.Close(); } catch { }
try { clientSocket?.Dispose(); } catch { }
}
}
await Task.Delay(1000 * 3);
BroadcastMessage($"Data sync complete!");
lock (locker)
{
running = false;
}
}
}
What I've tried (nothing below has had any effect):
Most of these were from 'solutions' from other stackoverflow posts.
Adding arbitrary delays into the mix
Making sure to explicitly close/dispose everything, in order, including the streams
Tried replacing the socket handling with their 'Insecure' counterparts.
Adjusting my read timeout to something arbitrarily long, in case a second wasn't enough.
Disabling/Re-enabling bluetooth on the server/collector before .Accept() ing a new connection (resorted to trying random stuff by this point)
Video:
I took a video of this happening.
The tablet in the back is the collector/server The tablet in the foreground is the master/client. When the video starts, the client is displaying some previous attempts, and the server app is in the background (but running). I demonstrate that the .Read works when the collector/server app is in the background, but not the foreground. Each request to begin data sync has a corresponding entry to the "console" (or a warning if I pressed it too soon)
https://youtu.be/NGuGa7upCU4
Summary:
To the best of my knowledge, my code is correct. I have no idea what else to change/fix to get this working more reliably. The actual connection seems like it is successful (based on logs from the server/collector, unfortunately not shown in the video), but the issue lies somewhere in the .Write (or .Read). ANy help, suggestions, or insight would be awesome.
Try the following, changed all to using:
private async Task AcceptLoopWorker()
{
int count = 0;
while (true)
{
try
{
BroadcastMessage("Listening for incoming connection...", DataSyncMessageType.Debug);
using (var serverSocket = BluetoothAdapter.DefaultAdapter.ListenUsingRfcommWithServiceRecord(nameof(GameDataSyncService), Java.Util.UUID.FromString(UUID)))
using (var clientSocket = serverSocket.Accept()) // This call blocks until a connection is established.
{
BroadcastMessage(string.Format("Connection received from {0}. Sending data...", clientSocket.RemoteDevice.Name), DataSyncMessageType.Info);
var bytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Hello World - {0}", string.Join(" ", Enumerable.Repeat(Guid.NewGuid(), ++count))));
await clientSocket.OutputStream.WriteAsync(bytes, 0, bytes.Length);
}
await Task.Delay(1000 * 3); // Give the master some time to close the connection from their end
}
catch (Java.IO.IOException ex)
{
BroadcastMessage(string.Format("IOException {0}: {1}", ex.GetType().FullName, ex.Message), DataSyncMessageType.Debug);
}
catch (Java.Lang.Exception ex)
{
BroadcastMessage(string.Format("Exception {0}: {1}", ex.GetType().FullName, ex.Message), DataSyncMessageType.Debug);
}
}
}
private async Task SyncDataWorker()
{
BroadcastMessage("Beginning data sync...");
foreach (var bondedDevice in BluetoothAdapter.DefaultAdapter.BondedDevices.OrderBy(d => d.Name))
{
try
{
using (var clientSocket = bondedDevice.CreateRfcommSocketToServiceRecord(Java.Util.UUID.FromString(UUID)))
{
BroadcastMessage(string.Format("Connecting to {0}...", bondedDevice.Name));
if (!clientSocket.IsConnected)
{
clientSocket.Connect();
}
if (clientSocket.IsConnected)
{
byte[] buffer = new byte[1024];
var readTask = clientSocket.InputStream.ReadAsync(buffer, 0, buffer.Length);
if (await Task.WhenAny(readTask, Task.Delay(1000)) != readTask)
{
BroadcastMessage("Read timeout...", DataSyncMessageType.Error);
break;
}
int bytes = readTask.Result;
BroadcastMessage(string.Format("Read {0} bytes.", bytes), DataSyncMessageType.Success);
if (bytes > 0)
{
var text = System.Text.Encoding.UTF8.GetString(buffer.Take(bytes).ToArray());
BroadcastMessage(text, DataSyncMessageType.Success);
break;
}
}
else
{
BroadcastMessage("Not Connected...", DataSyncMessageType.Error);
}
}
}
catch (Java.IO.IOException ex)
{
BroadcastMessage(string.Format("IOException {0}: {1}", ex.GetType().FullName, ex.Message), DataSyncMessageType.Debug);
}
catch (Java.Lang.Exception ex)
{
BroadcastMessage(string.Format("Exception {0}: {1}", ex.GetType().FullName, ex.Message), DataSyncMessageType.Debug);
}
}
await Task.Delay(1000 * 3);
BroadcastMessage("Data sync complete!");
lock (locker)
{
running = false;
}
}
I am trying to connect to an EPSON ePOS t88V printer from my .NET UWP application, using the drivers and SDK found here: https://download.epson-biz.com/modules/pos/index.php?page=prod&pcat=3&pid=36
I have deployed the official UWP sample app (https://download.epson-biz.com/modules/pos/index.php?page=single_soft&cid=5592&pcat=3&pid=36) to the POS, but the application wasn't able to discover the printer.
Then, I tried to build a minimal app, following the code snippets from the user manual:
using System;
...
using Epson.Epos.Epos2;
using Epson.Epos.Epos2.Printer;
namespace PrinterTest1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
Printer printer = null;
PrinterStatusInfo status = null;
public MainPage()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
printer = new Printer(Series.TM_T88, ModelLang.Ank);
printer.Received += Printer_Received;
printer.AddText("Deeeeerp.");
await printer.ConnectAsync("TCP:10.10.10.133", Printer.PARAM_DEFAULT); //this line throws an exception
await printer.BeginTransactionAsync();
await printer.SendDataAsync(Printer.PARAM_DEFAULT);
}
catch (Exception ex)
{
}
}
private void Printer_Received(Printer sender, ReceivedEventArgs args)
{
DoStuff();
}
private async void DoStuff()
{
try
{
status = printer.GetStatusAsync().GetResults();
if (status.Connection == Connection.True && status.Online == Online.True)
{
await printer.SendDataAsync(Printer.PARAM_DEFAULT);
}
}
catch (Exception ex)
{
}
}
}
}
but I am still not being able to connect to the printer. I am getting this exception:
{System.Exception: Exception from HRESULT: 0xA0048201 at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at PrinterTest1.MainPage.d__3.MoveNext()}
Take a look at the Universal Windows apps SDK
This allows you to connect to network printers.
See this code
Of course after installing the printer SDK
Printer printer = null;
try
{
printer = new Printer(Series.TM_T82, ModelLang.Ank);
printer.Received += Printer_Received;
printer.Buffer(order);
// Connect to printer through wifi
// Find printer from MAC address
await printer.ConnectAsync("TCP:64:EB:8C:2C:5B:4F", Printer.PARAM_DEFAULT);
await printer.BeginTransactionAsync();
// Send data to the printer
PrinterStatusInfo status = await printer.GetStatusAsync();
if (status.Connection == Connection.True && status.Online == Online.True)
{
await printer.SendDataAsync(Printer.PARAM_DEFAULT);
}
// Haven't figure out issue:
// If not delayed an ERR_PROCESSING is caught
await Task.Delay(1500);
//
await printer.EndTransactionAsync();
await printer.DisconnectAsync();
}
catch (Exception ex)
{
foreach (PropertyInfo prop in typeof(ErrorStatus).GetProperties())
{
if((int)prop.GetValue(null) == ex.HResult)
{
throw new Exception(prop.Name);
}
}
throw new Exception(ex.Message);
}
printer.ClearCommandBuffer();
printer.Received -= Printer_Received;
printer = null;
// Form a receipt from given order to the printer data buffer
public static void Buffer(this Printer printer, Order order)
{
// Receipt header
printer.AddTextAlign(Alignment.Center);
printer.AddTextSize(2, 1);
printer.AddText("MALAY PARLOUR\n");
printer.AddTextSize(Printer.PARAM_DEFAULT, Printer.PARAM_DEFAULT);
printer.AddText("234 PONSONBY RD, AUCKLAND\n");
printer.AddText("GST No: 106-338-302\n\n");
// Order time e.g. 01-01-2017 15:15
printer.AddText(String.Format("{0:dd}-{0:MM}-{0:yyyy} {0:HH}:{0:mm}\n", order.OrderDate));
// Print order details
foreach (OrderDetail od in order.OrderDetails)
{
printer.AddTextAlign(Alignment.Left);
// e.g. 2 * Seafood Laksa $16.50
printer.AddText(String.Format("{0,6} * {1,-22} {2,10:C2}\n",
od.Quantity,
od.Product.ProductName,
od.UnitPrice * od.Quantity));
// If item has remarks, add remarks in a new line
if (!String.IsNullOrEmpty(od.Remarks))
{
printer.AddText("\t" + od.Remarks + "\n");
}
printer.AddText("\n");
}
printer.AddTextAlign(Alignment.Right);
// If order has discount, print subtotal and discount
if (order.Discount != 0)
{
printer.AddText(String.Format("Subtotal: ${0:f2}\n", order.Subtotal));
printer.AddText(String.Format("Discount: {0:P2}\n", order.Discount));
}
// Print total. e.g. EftPos: $38.00
printer.AddTextSize(2, 1);
printer.AddText(String.Format("{0}: ${1:f2}\n\n", order.Payment, order.Total));
// Order footer
printer.AddTextAlign(Alignment.Center);
printer.AddTextSize(Printer.PARAM_DEFAULT, Printer.PARAM_DEFAULT);
printer.AddText("www.malayparlour.co.nz\n\n\n");
// Add a cut
printer.AddCut(Cut.Default);
}
private static void Printer_Received(Printer sender, ReceivedEventArgs args)
{
string callbackCode = Enum.GetName(typeof(CallbackCode), args.Code);
if (callbackCode.Contains("Error"))
{
throw new Exception(callbackCode);
}
}
Please check required device capabilities are enabled on Package.appxmanifest.
Required capabilities depend on how to connect to your printer (almost "Internet (Client & Server)" or "Bluetooth").
https://learn.microsoft.com/ja-jp/windows/uwp/devices-sensors/enable-device-capabilities
In my application I'm using a 9600 baud rate serial connection and I want to use a 115200 baud rate connection for data transfer.
I've disconnected from the old connection and set it to be null value, and set my serial connection to new connection with different baud rate.
The connection is unstable and I sometimes get a System.ObjectDisposedException - what did I miss?
The connection code
public string startConnection()
{
if (serial != null)
{
serial.Dispose();
}
foreach (string portname in SerialPort.GetPortNames())
{
serial = new SerialPort(portname, 9600, Parity.None, 8, StopBits.One);
serial.ReadTimeout = 5000;
serial.WriteTimeout = 5000;
serial.Handshake = System.IO.Ports.Handshake.None;
serial.NewLine = "\n";
string received = "";
try
{
serial.Open();
serial.DiscardInBuffer();
serial.Write(":09;BATTERY;");
Thread.Sleep(500);
received = serial.ReadLine();
if (received.Contains(";BATTERY;V="))
{
status = SERIAL_CONNECTED;
return portname;
}
}
catch (Exception err)
{
try
{
serial.Close();
status = DISCONNECTED;
}
catch (Exception)
{
// throw;
}
}
}
throw new Exception("couldn't connect to coms");
//return "couldn't connect to coms";
//this.Close();
}
Disconnect function:
public void disconnect ()
{
if (serial == null || serial.IsOpen==false ||status == DISCONNECTED)
return;
status = DISCONNECTED;
serial.Close();
serial = null;
}
The main program is:
private async void BurnOFP_click(object sender, RoutedEventArgs e)
{
startConnection();
some actions.............
disconnect();
var t = new Task(() =>
{
try
{
myUswm.startModemConnection(); // same but with different baud rate
}
catch (Exception e2) { MessageBox.Show(e2.Message); }
});
t.Start();
t.Wait();
modem = new XMODEM_FullDotNET(myUswm.getSerialPort(), XMODEM_FullDotNET.Variants.XModemCRC);
buff = File.ReadAllBytes(softwareFilePath_Text.Text);
if (buff.Length < 1)
{
MessageBox.Show("ERROR : wrong OFP file");
return;
}
if (myUswm.prepareOFPBurning()) // sends u to start transfer
{
if (isBurning == false)
{
isBurning = true;
modem._ProgressSent = 0;
myProgBar = new myProgressBar(modem);
myProgBar.StartTransfer(modem, buff.Length);
myProgBar.Show(); // show window
// got the Exception here!!!!!!!!!!
var t3 = new Task(() =>
{
modem.Send(buff);
});
............
}
else
MessageBox.Show("burning in progress..");
}
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
}
Thanks for any help
RESOLVED
my problem was A bad timing caused by closing and reopen the same port.
I've found the information in MSDN Serial class:
The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.
my solution was keeping the connection alive and change the baud rate and update the connection status in my application manually.
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.