使用Task.Run()进行Linq - 优化或瓶颈

时间:2016-10-15 22:37:39

标签: c# asp.net multithreading linq task

我正在尝试优化一些较旧的项目,确保它们“一直都是异步”,并且不会在较重的负载下崩溃。

我使用了以下代码段的变体,并且不确定Task.Run是优化还是可能的瓶颈。这种方法在一些较大的形式中得到了相当大的使用。

public static Task<List<SelectListItem>> ToMultipleSelectListItems<T>(this List<T> items, Func<T, string> nameSelector, Func<T, Guid> valueSelector, List<Guid> selected, Func<T, string> orderBy)
{
    Task<List<SelectListItem>> selectList = Task.Run(() => items.OrderBy(orderBy).Select(item =>
                    new SelectListItem
                    {
                        Text = nameSelector(item),
                        Value = valueSelector(item).ToString(),
                        Selected = selected.Contains(valueSelector(item))
                    }).ToList());
    return selectList;
}

示例电话..

model.Abilities = await (await Api.GetAbilities()).ToMultipleSelectListItems(
    x => x.Name, 
    x => x.Id, 
    model.Task.SelectedAbilitiesList, 
    x => x.OrderBy.ToString()
);

正如我所看到的,当前线程仍然需要在返回之前等待新线程响应。因此,在某些负载下,这可能会对CPU造成压力,甚至可能最大化线程。我没有看到好处。

对此方案中有关最佳做法的任何反馈都将不胜感激。

1 个答案:

答案 0 :(得分:4)

没有上升空间。此代码将对可伸缩性产生负面影响,并且根本没有任何好处。

  

有人看到了上升并且首先写了这个,

不,抱歉。

这只是一种效率较低的方式:

public static void cratio(String dna) {
    int c = 0;
    int g = 0;
    for(int i =0; i < dna.length(); i++) {
        if((dna.charAt(i) == 'c') || (dna.charAt(i) == 'C')) c++;
        if((dna.charAt(i) == 'g') || (dna.charAt(i) == 'G')) g++;
    }
    System.out.println("Number of 'C's in DNA: " + c + " and number of 'G's in DNA: " + g);
    int length = dna.length();
    double ratio = (double) (c+g)/length * 100;
    System.out.println("The ratio of 'C's and 'G's to the length of the DNA chain is: " + ratio + "%.");
}
  

对此方案中有关最佳做法的任何反馈都表示赞赏。

以下是相关的最佳做法:&#34;在ASP.NET&#34;上避免public static List<SelectListItem> ToMultipleSelectListItems<T>(this List<T> items, Func<T, string> nameSelector, Func<T, Guid> valueSelector, List<Guid> selected, Func<T, string> orderBy) { return items.OrderBy(orderBy).Select(item => new SelectListItem { Text = nameSelector(item), Value = valueSelector(item).ToString(), Selected = selected.Contains(valueSelector(item)) }).ToList()); } model.Abilities = (await Api.GetAbilities()).ToMultipleSelectListItems( x => x.Name, x => x.Id, model.Task.SelectedAbilitiesList, x => x.OrderBy.ToString() ); 。引用我的Intro to Async ASP.NET article

  

你可以通过等待Task.Run开始一些后台工作,但这样做没有意义。事实上,这实际上会通过干扰ASP.NET线程池启发式来损害您的可伸缩性。如果你有关于ASP.NET的CPU限制工作,最好的办法是直接在请求线程上执行它。作为一般规则,不要将工作排队到ASP.NET上的线程池。