使用async / await时这两种方法有什么区别

时间:2015-01-22 20:37:39

标签: c# entity-framework wcf asynchronous async-await

这两种方法有什么区别,它们的编译方式不同,但您可以使用await关键字以相同的方式调用它们。我想使用它们在Entity Framework 6.1上使用await关键字定义我的WCF接口。

只关心这两种方法中的哪一种对于使用WCF更正确,我使用服务工厂主机(没有添加服务引用),所以不要获得生成的异步方法。

    public static Task<string> MethodA()
    {
        Console.WriteLine("{0} - Running MethodA on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
        var task =  Task.Run(() =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("{0} - Done MethodA on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
            return string.Format("You ran MethodA on thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
        });
        Console.WriteLine("{0} - MethodA Returning on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
        return task;
    }

    public static async Task<string> MethodB()
    {
        Console.WriteLine("{0} - Running MethodB on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
        var task = Task.Run(() =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("{0} - Done MethodB on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
            return string.Format("You ran MethodB on thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
        });
        Console.WriteLine("{0} - MethodB Returning on thread {1}", DateTime.Now, System.Threading.Thread.CurrentThread.ManagedThreadId);
        return await task;
    }

在阅读完所有答案后,提供更多相关信息。区别在于状态生成,所以我想如果我们不打算使用状态,第一种方法更正确。

下面的

是解编译的代码

public static Task<string> MethodA()
{
  Console.WriteLine("{0} - Running MethodA on thread {1}", (object) DateTime.Now, (object) Thread.CurrentThread.ManagedThreadId);
  if (Program.CS\u0024\u003C\u003E9__CachedAnonymousMethodDelegatea == null)
  {
    // ISSUE: method pointer
    Program.CS\u0024\u003C\u003E9__CachedAnonymousMethodDelegatea = new Func<string>((object) null, __methodptr(\u003CMethodA\u003Eb__9));
  }
  Task<string> task = Task.Run<string>(Program.CS\u0024\u003C\u003E9__CachedAnonymousMethodDelegatea);
  Console.WriteLine("{0} - MethodA Returning on thread {1}", (object) DateTime.Now, (object) Thread.CurrentThread.ManagedThreadId);
  return task;
}

public static Task<string> MethodB()
{
  Program.\u003CMethodB\u003Ed__d stateMachine;
  stateMachine.\u003C\u003Et__builder = AsyncTaskMethodBuilder<string>.Create();
  stateMachine.\u003C\u003E1__state = -1;
  stateMachine.\u003C\u003Et__builder.Start<Program.\u003CMethodB\u003Ed__d>(ref stateMachine);
  return stateMachine.\u003C\u003Et__builder.Task;
}

[CompilerGenerated]
private static void \u003CMain\u003Eb__0()
{
  Program.CallServices();
}

[CompilerGenerated]
private static string \u003CMethodA\u003Eb__9()
{
  Thread.Sleep(TimeSpan.FromSeconds(2.0));
  Console.WriteLine("{0} - Done MethodA on thread {1}", (object) DateTime.Now, (object) Thread.CurrentThread.ManagedThreadId);
  return string.Format("You ran MethodA on thread {0}", (object) Thread.CurrentThread.ManagedThreadId);
}

[CompilerGenerated]
private static string \u003CMethodB\u003Eb__b()
{
  Thread.Sleep(TimeSpan.FromSeconds(2.0));
  Console.WriteLine("{0} - Done MethodB on thread {1}", (object) DateTime.Now, (object) Thread.CurrentThread.ManagedThreadId);
  return string.Format("You ran MethodB on thread {0}", (object) Thread.CurrentThread.ManagedThreadId);
}

2 个答案:

答案 0 :(得分:1)

前者将返回一个&#34;热门任务&#34;,这意味着它不会等待Task完成。

后者将异步等待操作完成,同时对调用者产生控制并在完成后恢复,然后将完成的任务返回给调用者。它还将生成一个封面下的状态机,负责调用任务继续。

如果您没有对异步操作中返回的值执行任何操作,请使用前者。另外,excepion handling

的区别也在于此

作为旁注,建议不要暴露async wrappers over sync methods。相反,请显式调用同步方法。

答案 1 :(得分:0)

这些选项的功能没有任何区别。唯一的区别是GetData1async方法(以构建async状态机为代价),而GetData则不是。这可能会增加很小的开销。

async方法与简单地返回Task之间的差异在于async方法在返回的任务中存储任何异常,而另一个则不存在。在你的情况下,由于所有这些方法在返回Task之前什么都不做,因此没有机会进行异常,因此它们的行为类似。

只要您了解正在发生的事情,由于GetData性能稍好一些,因此它是更好的选择。