在C#中并行运行多个操作



i在ASP.NET Web表单页面中具有以下代码,该页面基本上检查是否存在一些值,如果没有,则调用一个获取数据然后将其存储在缓存中的方法。获取数据的方法低于

ChartRenderingHelper.GenerateBidsStatusCreated(currYear.ToString(), currQuarter.ToString(), currYearType.ToString())

使用EF调用存储的proc和这3个调用所有呼叫所有呼叫单独的sp。并行但不确定如何更改当前的代码来执行此操作。

  bidsCreated.Value = DashboardCacheHelper.IsIncache(bidsCreatedKey, useCaching) ? DashboardCacheHelper.GetFromCache(bidsCreatedKey) : (string)DashboardCacheHelper.SaveCache(bidsCreatedKey, JsonConvert.SerializeObject(ChartRenderingHelper.GenerateBidsStatusCreated(currYear.ToString(), currQuarter.ToString(), currYearType.ToString())), DateTime.Now.AddDays(cacheDays));
            bidsSubmitted.Value = DashboardCacheHelper.IsIncache(bidsSubmittedKey, useCaching) ? DashboardCacheHelper.GetFromCache(bidsSubmittedKey) : (string)DashboardCacheHelper.SaveCache(bidsSubmittedKey, JsonConvert.SerializeObject(ChartRenderingHelper.GenerateBidsStatusSubmitted(currYear.ToString(), currQuarter.ToString(), currYearType.ToString())), DateTime.Now.AddDays(cacheDays));
            bidsClosed.Value = DashboardCacheHelper.IsIncache(bidsClosedKey, useCaching) ? DashboardCacheHelper.GetFromCache(bidsClosedKey) : (string)DashboardCacheHelper.SaveCache(bidsClosedKey, JsonConvert.SerializeObject(ChartRenderingHelper.GenerateBidsStatusClosed(currYear.ToString(), currQuarter.ToString(), currYearType.ToString())), DateTime.Now.AddDays(cacheDays));

我该如何并行进行这3个任务?使用TPL,我知道我们可以并行运行方法

Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());

这是推荐的方法,如果我说需要并行运行的12个操作使用所有调用SQL存储的procs使用EF,这是性能的问题。

您可以使用异步来实现这一目标,但是最好对实体框架代码进行异步实现,以添加和获取。

首先,我已经重构了代码以减少重复的代码,并通过引入方法GetOrAddAsync来使其更可读,此方法接受缓存键,useCaching的布尔值(这是什么是?)和ChartRenderingHelper方法的委托。目前尚不清楚哪种类型currQuartercurrYearType是。

private async Task<string> GetOrAddAsync(string cacheKey, bool useCaching, int cacheDays, DateTime currYear, ? currQuarter, ? currYearType, Action<string, string, string> cacheFactory)
{
    if(DashboardCacheHelper.IsIncache(cacheKey, useCaching))
    {
        return DashboardCacheHelper.GetFromCache(cacheKey);
    }
    return (string)(await DashboardCacheHelper.SaveCacheAsync(bidsClosedKey, JsonConvert.SerializeObject(cacheFactory(currYear.ToString(), currQuarter.ToString(), currYearType.ToString())), DateTime.Now.AddDays(cacheDays)).ConfigureAwait(false))
}

使用上述方法,您的分配代码然后变为

var bidsCreatedCacheTask = GetOrAddAsync(bidsCreatedKey, useCaching, cacheDays, currYear, currQuarter, currYearType, ChartRenderingHelper.GenerateBidsStatusCreated);
var bidsSubmittedCacheTask = GetOrAddAsync(bidsSubmittedKey, useCaching, cacheDays, currYear, currQuarter, currYearType, ChartRenderingHelper.GenerateBidsStatusSubmitted);
var bidsClosedCacheTask = GetOrAddAsync(bidsClosedKey, useCaching, cacheDays, currYear, currQuarter, currYearType, ChartRenderingHelper.GenerateBidsStatusClosed);
await Task.WhenAll(bidsCreatedCacheTask, bidsSubmittedCacheTask, bidsClosedCacheTask).ConfigureAwait(false);
bidsCreated.Value = await bidsCreatedCacheTask;
bidsSubmitted.Value = await bidsSubmittedCacheTask;
bidsClosed.Value = await bidsClosedCacheTask;

要记住的一件关键是将您的调用方法标记为async,如果是事件处理程序,则将是async void-但请牢记,否则应以任何不是事件处理程序的方法避免使用async void - 因为您受到事件处理程序的void返回类型的约束。

正如Lebigcat在评论中指出的那样,应将ConfigureAwait与在.NET框架上运行的异步代码一起使用以防止僵局,请阅读以了解为什么。

相关内容

  • 没有找到相关文章

最新更新