代码之家  ›  专栏  ›  技术社区  ›  VA systems engineer

使用异步/等待+TPL数据流在远程服务器上执行SQL select语句:CPU还是I/O绑定?

  •  0
  • VA systems engineer  · 技术社区  · 7 年前

    我的 C# WinForms 程序在上运行 Windows 7 客户端计算机并提交 SELECT 对a的查询 SQL Server 远程服务器上的实例(请参阅下面的DB代码段)。我认为我对处理查询结果的代码进行分类是正确的(一系列 DataTables )作为 CPU bound ,但我对如何对在客户机上运行的DB代码(见下文)进行分类没有信心。一方面,它与I/O相关,但我认为所有使用的I/O资源都在远程DB服务器上,由SQL server实例处理,而不是由Win 7客户端计算机处理,因此即使是我的DB代码 CPU-bound

    我是否应该将在客户端计算机上运行的DB代码视为 CPU限制 I/O bound ?或者,是否使用 TPL Dataflow 这一点没有意义吗?

    我的DB代码

    using (SqlConnection sqlConnection = new SqlConnection("Data Source=" + MachineName + ReplaceInstanceName + "; Initial Catalog=" + DbName + "; Integrated Security=True;Connection Timeout=10"))
    {
        using (SqlCommand sqlCommand = new SqlCommand())
        {
            sqlCommand.Connection = sqlConnection;
            sqlCommand.CommandType = CommandType.Text;
            sqlCommand.Parameters.AddWithValue("@SearchString", "%" + userProvidedSearchString + "%");
            sqlCommand.CommandText = queryString;
    
            sqlConnection.Open();
            SqlDataReader sqlDataReader = await sqlCommand.ExecuteReaderAsync(ct);
            dataTable_TableDataFromFieldQuery.Load(sqlDataReader);
            sqlConnection.Close();
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   TheGeneral    7 年前

    我是否应该将在客户端计算机上运行的DB代码视为 CPU绑定或I/O绑定

    我认为这里的经验法则是,如果它不在一个循环中并进行计算,那么它可能是IO限制的。任何访问网络资源、文件系统或等待设备响应的操作都可能是IO

    此外,并非程序中的所有内容都会占用CPU时间。当线程尝试从磁盘上的文件读取数据或通过网络发送TCP/IP数据包时,它所做的唯一事情就是将实际工作委托给设备、磁盘或网络适配器,并等待结果。

    花一个线程的时间等待是非常昂贵的。即使线程处于休眠状态,并且在等待结果时不消耗CPU时间,它也没有真正得到回报,因为这是对系统资源的浪费。

    您的请求是否为IO?DB有点模糊,但答案是肯定的。

    TPL数据流 或者,您只是不想创建线程或使用资源等待IO绑定的任务完成

    因此,异步/等待模式运行良好,或者您也可以使用TPL数据流块。前提是,你不会创建大量的任务,而这些任务就在那里等待着你。具有 ActionBlock 您可以配置最大任务量,并将其重新用于同时位于缓冲区中等待任务的所有项目。

    实例

    var block = new ActionBlock<MySomething>(
        mySomething => MyMethodAsync(mySomething),
        new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 50 });
    
    foreach (var something in ListOfSomethings)
    {
        block.Post(something );
    }
    
    block.Complete();
    await block.Completion;
    
        2
  •  0
  •   Xedni    7 年前

    数据存储在数据库服务器上的磁盘上,因此大部分IO将在那里进行,数据库引擎在那里查询数据并将数据返回给调用者(您的应用程序)。在从SQL Server检索到所有批数据之前,连接的两端都会有CPU和内存使用情况,此时您将对应用程序内存中的这些行进行操作。

    因此,您的机器没有受到IO攻击;这种情况发生在数据存在的地方。然而,您的代码导致IO发生在数据库服务器上,因此请从中解释您将要解释的内容。