如何实现异步方法及其同步方法?

我有一个方法,如Task GetContentAsync(string url) ,我的控制台应用程序还没有完全准备好在内部利用TPL,但可能在以后它会。

如何轻松地为此(或其他)方法编写同步包装器(不是替代实现)?

如果您的库需要同时实现同步和异步成员,那么您实现这两个成员。 没有快捷方式(假设这是一个可重用的库)。

 public async Task GetContentAsync(string url) { ... // Logic here, eg, using HttpClient } public string GetContent(string url) { ... // Duplicate logic here, eg, using WebClient } 

重复逻辑肯定是不幸的,但如果你试图走捷径,你实际上最终会陷入更糟糕的境地。 对于SO回答,“为什么”的细节有点长,但Stephen Toub涵盖了在他的经典一对博客文章“我应该为异步方法公开同步包装器吗?”时出现的问题。 和“我应该为同步方法公开异步包装器吗?”

顺便说一下,这两个问题的答案都是“不”。 另见这里的答案 。

以下是测试用例的代码,显示可以非常简单的方式执行此操作。 我还实现了一个GetContentAsync方法用于演示目的。

 using System.IO; using System.Net; using System.Threading.Tasks; namespace AsyncTestCase.Driver { public class AsyncTestCase { public AsyncTestCase() { } public string GetContent(string url) { Task task = this.GetContentAsync(url); return task.Result; } public async Task GetContentAsync(string url) { HttpWebRequest request = HttpWebRequest.CreateHttp(url); HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse; using (Stream stream = response.GetResponseStream()) { using (TextReader reader = new StreamReader(stream)) { string content = await reader.ReadToEndAsync(); return content; } } } } } 

这是代码,以显示它工作正常,易于使用:

 namespace AsyncTestCase.Driver { internal static class Program { private static void Main() { AsyncTestCase test = new AsyncTestCase(); string content = test.GetContent("http://www.google.com"); } } }