早些时候,我发布了与在客户端或服务中应用Async-Await相关的this问题。在继续讨论这个问题之前,请先阅读这个问题,因为它与问题紧密相关。
根据答案,我测试了C#4.0(TPL)和C#5.0(Async - Await)的代码。我使用服务提供的方法的异步和同步版本来调用服务,并比较每种情况下使用的线程数。 以下是我用于测试所用资源的代码:
主要方法
List<Task<string>> tasksList = new List<Task<string>>();
List<int> asyncThreads = new List<int>();
List<int> tplThreads = new List<int>();
Stopwatch watch = new Stopwatch();
watch.Start();
// Call the Async version of the method
for (int i = 0; i < 500; i++)
{
tasksList.Add(GetNameFromServiceAsync("Input" + i.ToString(), asyncThreads));
}
Task.WaitAll(tasksList.ToArray());
watch.Stop();
foreach (var item in asyncThreads.Distinct())
{
Console.WriteLine(item);
}
Console.WriteLine("(C# 5.0)Asynchrony Total Threads = " + asyncThreads.Distinct().Count());
Console.WriteLine(watch.ElapsedMilliseconds.ToString());
watch.Restart();
tasksList.Clear();
// Call the normal method
for (int i = 0; i < 500; i++)
{
tasksList.Add(GetNameFromService("Input" + i.ToString(), tplThreads));
}
Task.WaitAll(tasksList.ToArray());
watch.Stop();
foreach (var item in tplThreads.Distinct())
{
Console.WriteLine(item);
}
Console.WriteLine("(C# 4.0)TPL Total Threads" + tplThreads.Distinct().Count());
Console.WriteLine(watch.ElapsedMilliseconds.ToString());
异步和同步CAlls到服务
static async Task<string> GetNameFromServiceAsync(string name, List<int> threads)
{
Console.WriteLine(" Start Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
var task = await client.GetNameAsync(name);
threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
// Console.WriteLine("End GetNameFromServiceAsync Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
return task;
}
static Task<string> GetNameFromService(string name, List<int> threads)
{
var task = Task<string>.Factory.StartNew(() =>
{
threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
// Console.WriteLine("GetNameFromService Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
return client.GetName(name);
});
return task;
}
现在我已经研究了答案,并找出了以下结果:
我希望对我的调查结果有一些反馈意见,以便它对其他社区成员也有用。这是我之前问题的答案吗?
修改
Q值。我的观察结论是,如果我们使用Async-Await而不是TPL的Task.Factory.startNew,那么它将消耗较少的线程。这是怎么回事?如果没有,那么什么是与这些比较相关的正确方向?
Q值。因为我正在学习异步 - 等待,我想通过某种比较和可靠的代码证明它的价值。
答案 0 :(得分:14)
客户端async
(与同步代码相比)通常可以提高内存的成本的响应速度。
服务器端async
(与同步代码相比)通常通过减少内存/线程使用来提高可伸缩性。这些优点也适用于客户端async
(与多线程代码相比)。
这两者都是极端概括,并且肯定会出现他们错误的情况。
<强>更新强>
我的观察结论是,如果我们使用Async-Await ...,那么它将消耗较少的线程。
async
/ await
启用可维护的异步代码。他们自己并没有与创建线程有任何关系。但是,它们通常与Task.Run
(或Task.Factory.StartNew
)一起用于创建后台任务。
因为我正在学习异步 - 等待,我想通过某种比较和可靠的代码来证明它的价值。
async
和await
是编译器转换。它们使编写异步程序变得更容易 - 就是这样。
如果将它们与同步代码进行比较,那么您通常会看到改进的响应能力和/或可扩展性。如果将它们与现有的异步代码进行比较,那么它们通常会略微效率低,但在代码可维护性方面可以弥补这一点。