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

时间:2013-11-08 18:17:15

标签: c# .net task-parallel-library

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

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

2 个答案:

答案 0 :(得分:11)

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

public async Task<string> GetContentAsync(string url)
{
  ... // Logic here, e.g., using HttpClient
}

public string GetContent(string url)
{
  ... // Duplicate logic here, e.g., using WebClient
}

逻辑重复肯定是不幸的,但如果你试图走捷径,你实际上最终会陷入更糟糕的境地。对于SO答案,“为什么”的细节有点长,但Stephen Toub涵盖了在他的经典博客文章"Should I expose synchronous wrappers for asynchronous methods?""Should I expose asynchronous wrappers for synchronous methods?"

中包含的问题。 顺便说一下,两个问题的答案都是“不”。另请参阅my SO answer here

答案 1 :(得分:-1)

以下是测试用例的代码,显示可以非常简单的方式执行此操作。我还实现了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<string> task = this.GetContentAsync(url);
            return task.Result;
        }

        public async Task<string> 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");
        }
    }
}