如何同时实现异步方法和同步方法?[重复]

问题描述 投票:7回答:2

我有一个方法,如 Task<string> GetContentAsync(string url) 和我 控制台应用程序 还没有完全准备好在内部利用TPL,但也许在以后的日子里,它将会被利用。

我如何才能轻松地为这个(或其他)方法写一个同步包装器(而不是替代实现)?

c# .net task-parallel-library
2个回答
12
投票

如果你的库需要同时实现同步和异步成员,那么你就同时实现这两个成员。没有捷径(假设这是打算成为一个可重用的库)。

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在他的一对经典博文中涵盖了包装时出现的问题。"我应该为异步方法暴露同步包装器吗?""我应该为同步方法暴露异步包装器吗?"

另外,这两个问题的答案都是 "不"。另外,请看 我SO在这里回答.


-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");
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.