异步方法在桌面上没有阻塞但在服务器上阻塞?

时间:2012-07-16 21:47:55

标签: c# .net async-await

我做了一个简单的异步方法来异步调用SQL存储过程。

在我的控制台程序中,我在循环中调用此方法1000次,并在每次调用之间休眠1ms(Thread.Sleep)。 我在进入循环之前启动一个StopWatch,并在退出循环时停止它,并显示在循环中花费的时间。

在我的开发机器(Win7 - VS 2012 RC)上,我可以看到我期待看到的内容:

Completed in 1006 ms

这似乎是合乎逻辑的,考虑到异步方法的调用几乎立即返回(当到达第一个await关键字时),因此在等待之前执行代码时只需要很小的开销(6ms)。

然而,当我在安装了.NET Framework 4.5 RC的服务器计算机(Win2008 R2 SP1)上运行完全相同的代码时,代码运行正常,但是执行时间远远不是我期望的那样,没有与在我的开发机器上运行程序时获得的数据进行比较:

Completed in 15520 ms

这意味着以某种方式调用异步方法并不是真的异步调用,而第一个await似乎以某种方式阻塞?

这是我正在调用的异步方法的代码:

public async void CallSpAsync()
{
  var cmd = new SqlCommand("sp_mysp");
  {  
     var conn = new SqlConnection(connectionString);
     {
       cmd.Connection = conn;
       cmd.CommandType = CommandType.StoredProcedure;

       [...Filling command parameters here - nothing interesting...]

       await cmd.Connection.OpenAsync();                    
       await cmd.ExecuteNonQueryAsync();

       cmd.Dispose();
       cmd.Connection.Dispose();
     }
  }
}

这是主程序测试代码(循环):

Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
   CallSpAsync();
   Thread.Sleep(1);
}
sw.Stop();

我在两台机器上运行完全相同的可执行文件(在Release中编译的控制台程序)。

我想弄清楚为什么在服务器机器上运行程序时不能异步调用该方法。

有什么想法吗?

谢谢!

修改

问题与async / await无关,它正常工作,但是由于服务器上的计时器分辨率(由Stop​​Watch使用)比我工作站上的时间少15倍。代码的运行速度一点都不慢,只是计时器的分辨率导致了经过时间的计算。

见詹姆斯曼宁的答案。

1 个答案:

答案 0 :(得分:3)

这可能是服务器计算机上的计时器分辨率的函数。检查ClockRes实用程序。您可以在my comment on High accuracy DateTime.UtcNow中获得更多详细信息。