使用Async / Await

时间:2018-03-09 15:47:38

标签: c# .net performance asynchronous async-await

我已经就性能问题工作了几天。 在深入研究之前,我想快速解释具体服务的工作原理。

我有一个主服务获取请求并向其他微服务发送请求,但用户的单个入口点是主服务,我认为这个图像更容易理解:

Main Service and micro services

在主要服务从API获取请求之后,他做了一些逻辑,查询Db然后得到一个列表,列表上的每个项目都有Id,以获得主服务创建请求的每个项目的丰富程度。服务。

例如John请求主服务,主服务从Db获取90个项目的列表,然后主服务将创建90个微服务调用并返回包含90个项目的John单个响应。

现在问题只是关于创建异步调用微服务的正确方法。

这是我开发这个部分的方式:

GetDetailsAsync(Id, result.Items, request.SystemComponentId);

private static void GetDetailsAsync(string Id, List<MainItem> items, int systemId)
    {
            var getDetailsTasks = new List<Task>();

            foreach (MainItem single in items)
            {
                    getDetailsTasks.Add(SetSingleDetailsAsync(Id, single, systemId));
            }

            Task.WhenAll(getDetailsTasks);
    }

private static async Task SetSingleDetailsAsync(string Id, MainItem single, int systemId)
{
        single.ActivityExtendedDetails = await ProcessItemDetailsRequest.GetItemDetailsAsync(Id, single.TypeId,
            single.ItemId, systemId);
}

public static Task<JObject> GetItemDetailsAsync(string id, short type,
            string itemId, int systemId)
{
    var typeList = ActivityTypeDetails.GetActivityTypes();
    var url = GetActivityUrl(id, type, itemId, typeList);
    if (url == null)
    {
        throw new Failure($"No url defined for type {type}");
    }

    try
    {
        JObject res;
        using (var stream = client.GetStreamAsync(url).Result)
        using (var sr = new StreamReader(stream))
        using (var reader = new JsonTextReader(sr))
        {
            var serializer = new JsonSerializer();
            res = serializer.Deserialize<JObject>(reader);
        }
        return Task.FromResult(res);
    }
    catch(Exception ex)
    {
        Logger.Warn(
            $"The uri {url} threw exception {ex.Message}.");
        //[Todo]throw exception
        return null;
    }
}

此代码运行且结果不够好,CPU上升非常快并且变得非常高,我认为我在GetItemDetailsAsync func上有问题,因为我使用client.GetStreamAsync(url).Result 当使用.Result它阻止,直到任务完成。

所以我对GetItemDetailsAsync进行了一些小改动,试图真正实现异步:

public static async Task<JObject> GetItemDetailsAsync(string id, short type,
            string itemId, int systemId)
{
    var typeList = ActivityTypeDetails.GetActivityTypes();
    var url = GetActivityUrl(id, type, itemId, typeList);
    if (url == null)
    {
        throw new Failure($"No url defined for type {type}");
    }

    try
    {
        JObject res;
        using (var stream = await client.GetStreamAsync(url))
        using (var sr = new StreamReader(stream))
        using (var reader = new JsonTextReader(sr))
        {
            var serializer = new JsonSerializer();
            res = serializer.Deserialize<JObject>(reader);
        }
        return res;
    }
    catch(Exception ex)
    {
        Logger.Warn(
            $"The uri {url} threw exception {ex.Message}.");
        //[Todo]throw exception
        return null;
    }
}

但现在我得到null我应该从Async函数获取数据。 我尝试调试,我注意到一些奇怪的事情,一切都像我期望的那样发生:调用方法,执行微服务请求并获得响应但是来自端点的响应(在主服务上找到)在异步方法从微服务返回之前返回,这导致我得到null而不是我期望的数据。

我认为也许我没有正确使用async \ await,如果有人能解释这种行为是如何发生的话会很高兴

0 个答案:

没有答案