异步任务不会产生良好的响应



我正在尝试等待函数结束执行某些任务。他就是我的建筑

  • Windows 服务的类
  • 用于与设备通信的类,实例化为"ilon"。此类可以访问另一个类,该类允许我使用 Web 服务

从窗口服务中,我正在这样做:

Item_DataColl resultSet = ilon.read("Net/LON/10/LampDali1/nviRunHours");

以下是 "ilon" 类的读取函数的定义:

internal Item_DataColl read(string UCPTName)
{
       return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours").Result;
}

Ilonbind 变量与一个类相关联,该类允许我创建与 Web 服务的连接。所以他得到了一个名为"invoke_command_read"的函数,定义为:

public async Task<Item_DataColl> invoke_command_READ(string UCPTName)
{
    return await Task.Run(() => thread_command_READ_result(UCPTName));
}

在同一个类上,我终于有了这个函数:

private Item_DataColl thread_command_READ_result(string UCPTName)
{
    Item_DataColl resultSet = null;
    if (UCPTName != null)
    {
        try
        {
            OnProgressBarUpdate(progressBar.UnknownEnd);
            resultSet = connector.command_READ(UCPTName);
            readOperationDone(resultSet);
            OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
        }
        catch (Exception e)
        {
            OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
        }
        finally
        {
            OnProgressBarUpdate(progressBar.Invisible);
        }
    }
    return resultSet;
}

指令"resultSet = connector.command_READ(UCPTName("运行良好,在Web服务请求的结果之前不会返回任何结果。但是我无法获得网络服务的任何结果。

我的任务使用得好吗?

我的任务使用得好吗?

不。

这是

怎么回事:

  1. 实际操作是网络调用,因此非常适合async
  2. 但是代理为您提供了同步 API,因此您正在阻止线程。(不好(
  3. 所以invoke_command_READ将同步API包装在一个Task.Run中,所以它阻塞了一个线程池线程。(不好(
  4. 然后使用 Result read 块任务,每个请求阻塞两个线程并导致死锁。(真的很糟糕(

您的代码是同步过异步的,值得注意的是同时使用两种反模式(异步同步和异步过同步(。

要解决此问题,要么一直异步,要么一直同步。全程异步效率更高,但需要代理上的异步 API:

public async Task<Item_DataColl> invoke_command_READ(string UCPTName)
{
  Item_DataColl resultSet = null;
  if (UCPTName != null)
  {
    try
    {
      OnProgressBarUpdate(progressBar.UnknownEnd);
      resultSet = await connector.command_READAsync(UCPTName);
      readOperationDone(resultSet);
      OnConsoleWriting(string.Format("[READING] Lecture réussie : {0} = {1}", ((Dp_Data)resultSet.Item[0]).UCPTname, ((Dp_Data)resultSet.Item[0]).UCPTvalue[0].Value), ILonConnectorConsoleResultType.RESULT);
    }
    catch (Exception e)
    {
      OnConsoleWriting(e.ToString(), ILonConnectorConsoleResultType.ERROR);
    }
    finally
    {
      OnProgressBarUpdate(progressBar.Invisible);
    }
  }
  return resultSet;
}
internal Task<Item_DataColl> readAsync(string UCPTName)
{
  return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours");
}

一路同步可能会更容易,因为您的代理是同步的,而您的消费代码是同步的:

internal Item_DataColl read(string UCPTName)
{
  return ilonBind.invoke_command_READ("Net/LON/10/LampDali1/nviRunHours");
}
public Item_DataColl invoke_command_READ(string UCPTName)
{
  return thread_command_READ_result(UCPTName);
}

相关内容

  • 没有找到相关文章

最新更新