Reputation: 387
my C# mainwindow starts a taskfactory Task when a button is clicked. That Task should gather data from a Serial device, but not only once. It should collect the data in "realtime". The Serial module sends a request to that Serial device. when the device answeres, it should gave the data back to the mainwindow ( I tried it with a event) and starts collecting data again: Start Task:
private void menuStartLog_Click(object sender, RoutedEventArgs e)
{
Librarys.SerialCom Comport = new Librarys.SerialCom();
Task<string> serialThread = Task<string>.Factory.StartNew(() => Comport.ADVInfo(), TaskCreationOptions.LongRunning);
textBoxMain.Text = serialThread.Result;
}
This method is called:
public string ADVInfo()
{
openConnection();
if (Comport.IsOpen)
{
Comport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
while (true)
{
Console.WriteLine("Serial Task started.");
byte[] SerialRequest = new byte[3] { 0xF0, 0x02, 0x0D };
Comport.Write(SerialRequest.ToString());
Console.WriteLine("Serial Thread completed.");
//Here the task should return data to the mainwindow and request new data
}
}
return ("No open Comport!!!");
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
But the thread for Serial communication is blocking the main thread. Can i return data with out waiting in the Main thread, e.g. with a event?
Upvotes: 1
Views: 729
Reputation: 149618
Instead of blocking with .Result
, you should await
the Task
created by StartNew
. That way, control is yielded back to the message loop while the operation executes:
private async void menuStartLog_Click(object sender, RoutedEventArgs e)
{
Librarys.SerialCom Comport = new Librarys.SerialCom();
Task<string> serialThread = Task<string>.Factory.StartNew(() => Comport.ADVInfo(), TaskCreationOptions.LongRunning);
textBoxMain.Text = await serialThread;
}
If you want to generate multiple strings from the ComPort
, you can return an IEnumerable<string>
using yield return
.
Upvotes: 1