c#异步等待和异常

c#异步等待和异常,c#,exception,asynchronous,async-await,C#,Exception,Asynchronous,Async Await,我编写了一个visual studio 2015 c#程序,用于从自定义以太网设备读取一些数据。我需要使用异步等待指令,因为数据将在预定时间一起读取 我使用自定义的.NET库读取数据;这是我的代码: private void timerPollingData_Tick(object sender, EventArgs e) { readDevice_01(); readDevice_02(); // and so on for all devices ... } privat

我编写了一个visual studio 2015 c#程序,用于从自定义以太网设备读取一些数据。我需要使用异步等待指令,因为数据将在预定时间一起读取

我使用自定义的.NET库读取数据;这是我的代码:

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());                       
}
private void timerPollingData_Tick(对象发送方,事件参数e)
{
读取设备_01();
读取设备_02();
//如此类推,适用于所有设备。。。
}
专用异步void readDevice_01()
{
var结果=等待getDataDevice_01();
//保存数据
}
专用异步void readDevice_02()
{
var结果=等待getDataDevice_02();
//保存数据
}
私有任务getDataDevice_01()
{
MyCustomLibrary readDevice=新建MyCustomLibrary.Master();
返回Task.Factory.StartNew(()=>readDevice.ReadHoldingRegister(…一些参数…).ToString();
}
私有任务getDataDevice_02()
{
MyCustomLibrary readDevice=新建MyCustomLibrary.Master();
返回Task.Factory.StartNew(()=>readDevice.ReadHoldingRegister(…一些参数…).ToString();
}
我的疑问是: 处理每个任务异常的最佳实践是什么?我需要了解哪些设备从以太网中拔出或关闭,然后停止用于从以太网中检索数据的任务


非常感谢您的帮助。

您应该避免
异步void
;对除异步事件处理程序之外的所有内容使用
async Task
。有关更多信息,请参阅我的文章

此外,您不应使用
StartNew
;这是一个低级的、非常危险的API,默认参数值不合适。使用
Task。运行
而不是
StartNew
。有关更多信息,请参阅我在上的博客文章

我需要使用异步等待指令,因为数据将在预定时间一起读取

异步是并发的一种形式,可用于
任务。如果设备API没有异步方法,请运行

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();                       
}
如果您的API有一个
ReadHoldingRegisterAsync
方法,那么这将更自然地表示为:

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();
}
private async void timerPollingData_Tick(对象发送方,事件参数e)
{
var task1=readDevice_01Async();
var task2=readDevice_02Async();
//如此类推,适用于所有设备。。。
等待任务。WhenAll(任务1,任务2,…);
}
专用异步任务readDevice_01Async()
{
var result=等待getDataDevice_01Async();
//保存数据
}
专用异步任务getDataDevice_01Async()
{
MyCustomLibrary readDevice=新建MyCustomLibrary.Master();
var result=wait readDevice.ReadHoldingRegisterAsync(…一些参数…);
返回result.ToString();
}
我的疑问:处理每个任务异常的最佳实践是什么?我需要了解哪些设备从以太网中拔出或关闭,然后停止用于从以太网中检索数据的任务

从任务中获取异常的最佳实践是等待异常


您不必担心在任务引发异常后停止任务。当任务报告其异常时,它已经停止。

不要使用
async void
,它仅用于事件处理程序。你不能等待它或捕捉任何异常。如果您不想返回任何内容,请使用
async Task
。@PanagiotisKanavos-很好的标准建议,但TimerTick是一个事件处理程序。因此,传播到两个
async void
方法并不是很好,但也不是完全错误。我们不需要知道是哪个Visual Studio,但一定要告诉我们这是Windows服务还是WinForms或。。。应用程序。作为建议,您可以创建一个
Master
来获取Modbus数据,并在请求数据时记录其获取的内部异常的所有信息。您不应该使用
async void
(改为使用
async Task
),也不应该使用
Task.Factory.StartNew
(使用
Task.Run
)。您好,Stephen,非常感谢您提供的示例代码;我不知道我的自定义库(或API)是否有读取数据的异步方法。因此,现在我尝试像第一个代码示例一样修改我的代码。下周我希望进行一些测试;然后用我的结果更新此讨论,非常感谢