我的await
关键字的理解是,继await
合格声明代码为声明的延续运行,一旦它完成。SemaphoreSlim.WaitAsync继续码
因此,下面的两个版本应该产生相同的输出:
public static Task Run(SemaphoreSlim sem)
{
TraceThreadCount();
return sem.WaitAsync().ContinueWith(t =>
{
TraceThreadCount();
sem.Release();
});
}
public static async Task RunAsync(SemaphoreSlim sem)
{
TraceThreadCount();
await sem.WaitAsync();
TraceThreadCount();
sem.Release();
}
但他们没有!
下面是完整的程序:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace CDE
{
class Program
{
static void Main(string[] args)
{
try
{
var sem = new SemaphoreSlim(10);
var task = Run(sem);
Trace("About to wait for Run.");
task.Wait();
Trace("--------------------------------------------------");
task = RunAsync(sem);
Trace("About to wait for RunAsync.");
task.Wait();
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
Trace("Press any key ...");
Console.ReadKey();
}
public static Task Run(SemaphoreSlim sem)
{
TraceThreadCount();
return sem.WaitAsync().ContinueWith(t =>
{
TraceThreadCount();
sem.Release();
});
}
public static async Task RunAsync(SemaphoreSlim sem)
{
TraceThreadCount();
await sem.WaitAsync();
TraceThreadCount();
sem.Release();
}
private static void Trace(string fmt, params object[] args)
{
var str = string.Format(fmt, args);
Console.WriteLine("[{0}] {1}", Thread.CurrentThread.ManagedThreadId, str);
}
private static void TraceThreadCount()
{
int workerThreads;
int completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Trace("Available thread count: worker = {0}, completion port = {1}", workerThreads, completionPortThreads);
}
}
}
这里是输出:
[9] Available thread count: worker = 1023, completion port = 1000
[9] About to wait for Run.
[6] Available thread count: worker = 1021, completion port = 1000
[9] --------------------------------------------------
[9] Available thread count: worker = 1023, completion port = 1000
[9] Available thread count: worker = 1023, completion port = 1000
[9] About to wait for RunAsync.
[9] Press any key ...
我缺少什么?
您有两种方法之间的一个非常重要的区别差异,你的第一个方法更相当于拥有'等待sem.WaitAsync()ConfigureAwait(假);'你的第二个方法。一旦你得到的代码行为相同,通过拖延像答案建议尝试运行你的测试程序在一个按钮的OnClick,而不是在控制台的应用程序。 – 2014-09-03 22:28:44