异步同步同步c#简单控制台应用程序

时间:2014-03-13 16:12:20

标签: c# asynchronous .net-4.5

我正在尝试编写我的第一个异步应用并确保其同时工作。问题是我同步写了相同的应用程序,我没有看到时差。

class Program
{
 private static List<string> List1 = new List<string>();
 Stopwatch s = new Stopwatch();
    s.Start();      
    var waitOne = Load(1000);
 Task.WhenAll(waitOne);
  Console.WriteLine("Done Time:" + (s.ElapsedMilliseconds / 1000).ToString());
    Console.ReadLine();
}
    static async Task Load(int i)
{
    for (int y = 0; y < i; y++)
    {
        List1.Add(callWcf(y).Result);
    }

    await Task.Yield();
}
static async Task<string> callWcf(int i)
{
    string here;

    using (ServiceReference1.Client client = new AsyncTests.ServiceReference1.Client())
    {
        here = client.GetThisInt(i);
    }
    await Task.Yield();
    return here;

}
}

WCF服务是我通过此链接http://msdn.microsoft.com/en-us/library/bb386386.aspx;

构建的简单服务

返回&#34;您输入了{0}&#34;

我同步执行相同的代码,并且它们都需要8秒进行1000次迭代,这很快但我认为我的异步是错误的,因为它应该比同步更快。我已经按照教程,听了几个播客,我知道我错过了什么,但我不知道是什么。

1 个答案:

答案 0 :(得分:2)

我有async intro你可能会觉得有帮助。

异步代码并不总是运行得更快。实际上,对异步代码的直接逐行转换通常运行较慢。异步代码的主要优点是并发性:它在异步操作正在进行时释放调用线程以执行其他工作。

要查看您的代码:

Task.WhenAll(waitOne);

这实际上并没有做任何事情。 WhenAll将返回在Task完成时完成的waitOne,但会忽略从WhenAll返回的任务。

List1.Add(callWcf(y).Result);

这里你的代码主演一个异步操作(callWcf)然后转身并立即同步阻止等待它完成(Result)。

await Task.Yield();

这段代码毫无意义。显然,只有那些使async方法不包含await的编译器警告静音。

here = client.GetThisInt(i);

此处代码再次同步阻塞。

正如我在async best practices article中所描述的那样,async的原则之一就是“一直使用异步”。从最低级别(寻找任何基于I / O的东西)进行此操作最简单,并逐步完成。在这种情况下,最好的起点是WCF调用:

static async Task<string> CallWcfAsync(int i)
{
  using (ServiceReference1.Client client = new AsyncTests.ServiceReference1.Client())
  {
    return await client.GetThisIntAsync(i);
  }
}

我还更改了方法名称以匹配TAP conventions

接下来,您将转到该方法的调用方:

static async Task Load(int i)
{
  for (int y = 0; y < i; y++)
  {
    List1.Add(await CallWcfAsync(y));
  }
}

或者如果您想同时执行多个呼叫:

static async Task LoadAsync(int i)
{
  var tasks = Enumerable.Range(0, i).Select(y => CallWcfAsync(y));
  List1.AddRange(await Task.WhenAll(tasks));
}

最后,您的Main方法必须阻止任务;这是允许调用ResultWait的非常罕见的情况之一:

LoadAsync(1000).Wait();