【发布时间】:2016-12-30 16:54:45
【问题描述】:
我已经组装了一个小型测试工具来诊断为什么我的 C# 数据处理应用程序的吞吐量(其核心功能使用非阻塞 IO 从远程数据库服务器批量选择 100 条记录并对其执行简单处理)比它可能低得多。我观察到,在运行时,应用程序在 CPU (
我的问题是,当客户端服务器能够显着提高吞吐量时,为什么 TPL 不增加正在运行的任务数量或以其他方式增加吞吐量?
简化代码摘录:
public static async Task ProcessRecordsAsync()
{
int max = 10000;
var s = new Stopwatch();
s.Start();
Parallel.For(0, max, async x =>
{
await ProcessFunc();
});
s.Stop();
Console.WriteLine("{2} Selects completed in {0} ms ({1} per ms).", s.ElapsedMilliseconds, ((float)s.ElapsedMilliseconds) / max, max);
}
public static async Task ProcessFunc()
{
string sql = "select top 100 MyTestColumn from MyTestTable order by MyTestColumn desc;";
string connStr = "<blah>...";
using (SqlConnection conn = new SqlConnection(connStr))
{
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
DbDataReader rdr = await cmd.ExecuteReaderAsync();
while (rdr.Read())
{
// do simple processing here
}
rdr.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
【问题讨论】:
-
对代码运行分析器以查看使用时间最长的代码,然后确定是否应该优化该代码。
-
@RudyTheHunter,这是最耗时的非阻塞数据库调用,但这些调用几乎不需要客户端上的资源,并且应该很容易并行化,因为我可以运行 45 个实例应用程序不会遇到客户端上的任何资源瓶颈。我试图理解的是为什么我不能在单个进程中获得相同程度的并行化。
-
看起来代码每次都从数据库中选择相同的前 100 行。我想知道您是否一遍又一遍地打相同的 100 行。您说您正在执行非阻塞数据库调用,但对它们进行简单更新。您是否需要选择不同的 100 行作为更好的示例?我认为您需要分享有关此过程中发生的事情的更多细节。
-
数据库中的行被运行在不同机器上的完全独立的进程慢慢改变,我的应用程序只执行 SELECT,没有 INSERT、UPDATE 或 DELETE。不过,我认为这些细节中的任何一个都与核心问题无关,即为什么我可以通过运行多个进程获得约 45 倍的吞吐量,但不能在单个进程中获得更多吞吐量。
标签: c# task-parallel-library throughput