触发 HttpClient 的更简单方法(可能没有任务)?

Simplier way to trigger HttpClient (maybe without Task)?

我正在开发将使用我自己的 REST endpoints 的应用程序(我有自己的 WebApi 项目)。现在我尝试构建可在该端点上运行的应用程序。

基于 this MSDN 教程,我做了这样的事情:

为了测试,我制作了 Console Core 应用程序。主要 class 看起来像这样:

class Program
{
    public static HttpDataService http = new HttpDataService("authorization token here");

    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        RunAsync().GetAwaiter().GetResult();
    }

    static async Task RunAsync()
    {
        var data = await http.Get("Default");
    }
}

我的主要 Http class 看起来像这样:

public class HttpDataService
{
    public HttpDataService(string token)
    {
        this.HttpClient = new HttpClient();
        this.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    }

    private HttpClient HttpClient { get; set; }

    public async Task<object> Get(string controller)
    {
        object data;
        HttpResponseMessage response = await this.HttpClient.GetAsync(UrlService.BuildEndpoint(controller));

        if (response.IsSuccessStatusCode)
        {
            data = await response.Content.ReadAsAsync<object>();
            return data;
        }
        else
        {
            throw new Exception(); //todo
        }
    }
}

我不喜欢额外的步骤,我需要为 运行 任务执行方法(Main 方法中的 RunAsync.GetAwaiter...)。

有没有更简单的方法来使用我自己的端点?也许其他一些不需要额外方法的库(这样,static Async Task Run)?有没有办法像这样触发方法:

http.Get("Projects");

没有我之前写的RunAsync()方法?

PS。该控制台应用程序工作正常(我从我的 WebApi 项目的 Default 控制器获取值)

编辑

这样看起来更人性化:

static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        Task get = http.Get("default");

        RunAsync(get).GetAwaiter().GetResult();
    }

    static async Task RunAsync(Task endpoint)
    {
         await endpoint;
    }

但是如何从 endpoint 中获取?

您的代码有 2 个问题。第一个是你的 RunAsync 方法 returns Task 而你的方法 HttpDataService.Get return Task<object>。要从端点获得结果,RunAsync 应该 return Task<object>。当你等待这个任务时,你会得到一个包含你结果的对象。

对于.GetAwaiter().GetResult(),有2个选项。首先,您可以创建一个 static async Task MainAsync 并在其中 运行 所有代码并通过调用 MainAsync().GetAwaiter().GetResult() 从非同步 Main 方法调用此方法。在 C# 7.1 之前,这是要走的路。

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
}

static async Task MainAsync(string[] args)
{
    // Run your async code here
}

如果您使用 C# 7.1,您可以使您的 Main-方法异步 (static async Task Main(string[] args)),然后您可以从那里直接调用您的异步代码。

static async Task Main(string[] args)
{
    // Run your async code here
}

你可以使用助手class

public static class AsyncHelper  
{
    private static readonly TaskFactory _taskFactory = new
        TaskFactory(CancellationToken.None,
                    TaskCreationOptions.None,
                    TaskContinuationOptions.None,
                    TaskScheduler.Default);

    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
        => _taskFactory
            .StartNew(func)
            .Unwrap()
            .GetAwaiter()
            .GetResult();

    public static void RunSync(Func<Task> func)
        => _taskFactory
            .StartNew(func)
            .Unwrap()
            .GetAwaiter()
            .GetResult();
}

允许你这样做:

static async Task RunAsync(Task endpoint) {
   AsyncHelper.RunSync(() => endpoint());  
}

PS。看看这里 Ms AsyncHelper and here C# Async Tips & Tricks

你应该Main异步。

注意:仅适用于现代 c#

static async Task Main(string[] args)
{
    var result = await http.Get("default");
}