Reputation: 37
I wrote a visual studio 2015 c# program for reading from a custom Ethernet device some data. I need to use async await instructions because the data will be read all together on scheduled times.
I use a custom .NET library for read data; this is my code:
private void timerPollingData_Tick(object sender, EventArgs e)
{
readDevice_01();
readDevice_02();
// and so on for all devices ...
}
private async void readDevice_01()
{
var result = await getDataDevice_01();
// Save data
}
private async void readDevice_02()
{
var result = await getDataDevice_02();
// Save data
}
private Task<string> getDataDevice_01()
{
MyCustomLibrary readDevice = new MyCustomLibrary.Master();
return Task.Factory.StartNew(() => readDevice.ReadHoldingRegister(... some parameters ...).ToString());
}
private Task<string> getDataDevice_02()
{
MyCustomLibrary readDevice = new MyCustomLibrary.Master();
return Task.Factory.StartNew(() => readDevice.ReadHoldingRegister(... some parameters ...).ToString());
}
My doubt: what is the best practice for handle exception of each Task? I need to understand what devices are unplug from Ethernet or switch off and then STOP the TASK used to retrieve data from it.
Thanks a lot in advance for your help.
Upvotes: 2
Views: 3066
Reputation: 456437
You should avoid async void
; use async Task
for everything except async event handlers. For more information, see my article on async best practices.
Also, you should not use StartNew
; it's a low-level, very dangerous API with inappropriate default parameter values. Use Task.Run
instead of StartNew
. For more information, see my blog post on StartNew
is dangerous.
I need to use async await instructions because the data will be read all together on scheduled times.
Asynchrony is one form of concurrency, which you can use with Task.Run
if your device API does not have asynchronous methods:
private async void timerPollingData_Tick(object sender, EventArgs e)
{
var task1 = readDevice_01();
var task2 = readDevice_02();
// and so on for all devices ...
await Task.WhenAll(task1, task2, ...);
}
private async Task readDevice_01()
{
var result = await Task.Run(() => getDataDevice_01());
// Save data
}
private string getDataDevice_01()
{
MyCustomLibrary readDevice = new MyCustomLibrary.Master();
return readDevice.ReadHoldingRegister(... some parameters ...).ToString();
}
If your API had a ReadHoldingRegisterAsync
method, then this would be more naturally expressed as:
private async void timerPollingData_Tick(object sender, EventArgs e)
{
var task1 = readDevice_01Async();
var task2 = readDevice_02Async();
// and so on for all devices ...
await Task.WhenAll(task1, task2, ...);
}
private async Task readDevice_01Async()
{
var result = await getDataDevice_01Async();
// Save data
}
private async Task<string> getDataDevice_01Async()
{
MyCustomLibrary readDevice = new MyCustomLibrary.Master();
var result = await readDevice.ReadHoldingRegisterAsync(... some parameters ...);
return result.ToString();
}
My doubt: what is the best practice for handle exception of each Task? I need to understand what devices are unplug from Ethernet or switch off and then STOP the TASK used to retrieve data from it.
The best practices for getting exceptions from tasks are to await
them.
You don't have to worry about stopping a task after it raised an exception. By the time the task reports its exception, it has already stopped.
Upvotes: 2