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

C# 异步任务将不会产生良好的响应,c#,.net,web-services,asynchronous,task,C#,.net,Web Services,Asynchronous,Task,我正在尝试等待函数结束以执行某些任务。这是我的架构 windows服务的类 用于与设备通信的类,实例为“ilon”。这个类可以访问另一个类,该类允许我使用Web服务 在windows服务中,我正在执行以下操作: Item_DataColl resultSet=ilon.read(“Net/LON/10/LampDali1/nviRunHours”) 下面是“ilon”类的读取函数的定义: Ilonbind变量与一个类相关联,该类允许我创建与webservice的连接。所以他得到了一个名为“i

我正在尝试等待函数结束以执行某些任务。这是我的架构

  • windows服务的类
  • 用于与设备通信的类,实例为“ilon”。这个类可以访问另一个类,该类允许我使用Web服务
在windows服务中,我正在执行以下操作:

Item_DataColl resultSet=ilon.read(“Net/LON/10/LampDali1/nviRunHours”)

下面是“ilon”类的读取函数的定义:

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

public async Task<Item_DataColl> invoke_command_READ(string UCPTName)
{
    return await Task.Run(() => thread_command_READ_result(UCPTName));
}
指令“resultSet=connector.command_READ(UCPTName)”工作正常,在webservice请求的结果出来之前不会返回任何结果。但我无法得到任何结果的Web服务

我的任务用得好吗

我的任务用得好吗

没有

下面是发生的事情:

  • 实际操作是网络调用,因此它非常适合
    async
  • 但是代理为您提供了同步API,因此您阻塞了一个线程。(不好)
  • 因此
    invoke\u command\u READ
    将同步API包装在
    任务中。Run
    ,因此它会阻止线程池线程。(不好)
  • 然后,
    read
    使用
    Result
    阻塞任务,每个请求阻塞两个线程,然后执行。(非常糟糕)
  • 您的代码是syncoverasyncoversync,这是因为同时使用了两种反模式(and)

    要解决这个问题,可以一直异步,也可以一直同步。Async始终更高效,但需要在代理上使用Async 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");
    }
    

    好的,所以我使用的API不提供异步API。所以通过使用同步方式,我试着按照你说的做,但这会阻止主线程,不是吗?我必须创建一些东西在另一个线程上运行代码并返回结果?@NFrb:您的原始代码故意阻塞了主线程。如果您不想阻止主线程,那么可以使用
    等待任务。运行
    。好的,我会重新开始,我认为这是找到解决方法的更好方法。我会和你保持同步
    
    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;
    }
    
    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);
    }