对Linq使用Task.Run()-优化或瓶颈 [英] Using Task.Run() for Linq - optimization or bottleneck

查看:105
本文介绍了对Linq使用Task.Run()-优化或瓶颈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm in the process of trying to optimize a few older projects, making sure they're "async all the way" and won't crash under heavier loads.

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

I've used variations of the snippet below and feel unsure if the Task.Run is an optimization or a possible bottleneck. This method gets quite heavy use in some of the larger forms.

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造成压力,甚至可能使线程数最大化.我看不出有什么好处.

As I see it, the current thread would still need to wait for the new threads response before returning. So, under some load this would possibly create a strain on the CPU and perhaps even max out threads. I fail to see an upside.

在这种情况下,有关最佳做法的任何反馈将不胜感激.

Any feedback on best practice in this scenario would be appreciated.

推荐答案

没有好处.该代码将对可伸缩性产生负面影响,根本没有任何好处.

There's no upside. This code will negatively impact scalability and provide no benefit at all.

有人看到了一个好处,并首先写了这个,

Someone saw an upside and wrote this in the first place,

不,对不起.

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

It's just a less-efficient way of doing this:

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()
);

在这种情况下,有关最佳做法的任何反馈都将不胜感激.

Any feedback on best practice in this scenario would be appreciated.

这里是相关的最佳实践:在ASP.NET上避免使用Task.Run".引用我的异步ASP.NET文章简介:

Here's the relevant best practice: "avoid Task.Run on ASP.NET". To quote my Intro to Async ASP.NET article:

您可以通过等待Task.Run开始一些后台工作,但这样做没有任何意义.实际上,通过干扰ASP.NET线程池启发式方法,这实际上会损害您的可伸缩性.如果要在ASP.NET上进行CPU限制的工作,最好的选择是直接在请求线程上执行它.通常,不要将工作排队到ASP.NET上的线程池中.

You can kick off some background work by awaiting Task.Run, but there’s no point in doing so. In fact, that will actually hurt your scalability by interfering with the ASP.NET thread pool heuristics. If you have CPU-bound work to do on ASP.NET, your best bet is to just execute it directly on the request thread. As a general rule, don’t queue work to the thread pool on ASP.NET.

这篇关于对Linq使用Task.Run()-优化或瓶颈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆