在后台运行查询会增加CPU使用率

时间:2018-02-06 19:42:28

标签: c# linq cpu-usage

我有一个每隔几秒运行一次的功能。

private void MyTimer_Tick(object sender, EventArgs e)
{
  Task.Run(() => UpdateData());
}

private void UpdateData()
{ 
  //i have some other functions here 
  updateCache(list1, cachelist);
}


private void updateCache(List<T> searchResults, List<T> cacheList)
{
   var result = searchResults.Where(x => !cacheList.Any(y => x.Number == y.Number && x.FileName == y.FileName));
   cacheList.AddRange(result);
}
updatecache()函数中的linq查询尝试比较两个列表并更新list1(如果在cachelist中找到一些新值)。这个linq查询正在增加CPU使用率非常高,并且只要窗口打开,此函数每隔几秒运行一次,CPU使用率非常高。我怎样才能做得更好?

2 个答案:

答案 0 :(得分:2)

cacheList成为HashSetDictionary,这样您就不必再循环它了。

另一个选项是使searchResults成为一个不同的类型,并在添加一个项时给它一个事件,然后订阅该事件以在cacheList中添加该项。但这实际上取决于您的架构是否允许它。

答案 1 :(得分:1)

你可以做类似下面提供的解决方案。部分性能问题可能是无意识/不受控制的并发性。如果你想让updateCache同时运行多次,你应该引入一些代码来控制它(调节线程数等)。但你可能不想要而且不需要它。更好的解决方案可能是防止重新进入updateCache。

    object _updateLock = new object();
    bool _isUpdating = false;
    bool IsUpdating
    {
        get { return _isUpdating; }
        set
        {
            lock (_updateLock)
            {
                _isUpdating = value;
            }
        }
    }

    private void UpdateData()
    {
        if (!IsUpdating)
        {
            IsUpdating = true;
            updateCache(list1, cachelist);
            IsUpdating = false;
        }          
    }


    ConcurrentDictionary<Tuple<int, string>, T> cache = new
          ConcurrentDictionary<Tuple<int, string>, T>();

    public void updateCache()
    {

        foreach (var sr in searchResults)
        {
            var key = new Tuple<int, string>(sr.Number, sr.FileName);
            cache[key] = sr;
        }
    }