have the Arduino who send the data continuously without caring the delay and i want to put the delay on my display in C#, so i can print all the value without missing a thing but in every line i want to put a delay for (let say) two seconds. I did with Thread.Sleepsomehow it blocked and delayed my UI and Task.Delay won't help. Does anyone knows how to fix this? unionwells france
Instead of invoking the UI thread (which you don't have the control te limit). Put the data into a variable/field and use a DispatcherTimer to display it. This way you control the update speed on the screen. site
Here's an example:
private SerialPort mySerialPort;
private readonly StreamWriter sw = new(@"D:\MAAT\readcoba.csv");
// create a dispatcher timer
private DispatcherTimer timer = new DispatcherTimer(TimeSpan.FromMilliseconds(200), DispatcherPriority.Normal, UpdateLabel, Dispatcher.CurrentDispatcher)
// a lock object to use threadsafe object access
private object lockObject = new Object();
private static void UpdateLabel(object sender, EventArgs e)
{
// never update UI within a lock (which is used on other threads)
// Create a copy or if the field is only written (on the other end) copy the reference.
string[] data;
lock(lockObject)
data = _arduinoData; // You don't need to create a copy, but that's only because the _arduinoData isn't used.
foreach (string item in data)
{
// ????? why write to the same label over and over? Rather use a StringBuilder
raw_data_label.Content = raw_data_label.Content.ToString().Contains("Nothing to Display") ?
$"{item}" : $"{raw_data_label.Content}" + $"{item}";
}
}
public MainWindow()
{
InitializeComponent();
Configure();
}
private void Configure()
{
mySerialPort = new(Port())
{
BaudRate = 9600,
Parity = Parity.None,
StopBits = StopBits.One,
DataBits = 8,
};
mySerialPort.DataReceived += DataReceivedHandler;
Thread.Sleep(2000);
mySerialPort.Open();
}
private string Port()
{
string port = "";
string[] ports = SerialPort.GetPortNames();
foreach (string x in ports)
{
port = x;
}
return port;
}
private string[] arduinoData;
private void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
// It's still not work
// await Task.Delay(2000); <-- don't delay here!
string indata = mySerialPort.ReadExisting();
string[] arrData = indata.Split(',');
sw.WriteLine(indata);
// lock and assigny the reference to the field (this is only allowed when the reference isn't used anymore _(if the string array isn't yours, Use a ToArray to create a copy)_
// That's why the s.WriteLine(..) is move above this.
lock(lockObject)
arduinoData = arrData;
}
private void WindowClosed(object sender, EventArgs e)
{
sw.Close();
mySerialPort.Close();