我可以得到一些反馈(这是一个足够好的问题吗?) [英] May I have some feedback (is that a good enough question?)

查看:64
本文介绍了我可以得到一些反馈(这是一个足够好的问题吗?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好b $ b

我正在尝试创建一个有序队列。我一直有一个问题,我的消息没有以正确的顺序解析,因为很多都是在同一时间到期。



我本可以确保我首先订购了列表,但是如果有紧急消息,那么应该跳过我已经加载的队列。



所以我自己创建了orderedQueue。我保持足够的通用性,我可以在其他地方使用它。 SteamQueue()方法对于Reactive Extension非常有用。



这个队列已经是我系统中的主要瓶颈了,所以我可以得到一些关于它的效率的反馈,或者如果有办法让它更加如此。



谢谢^ _ ^



这里是:

 使用系统; 
使用 System.Collections.Generic;
使用 System.Linq;
使用 System.Threading;

命名空间工具
{
public class OrderedQueue< T>
{
private readonly Lazy< List< T>> _queue = new Lazy< List< T>>(()=> new List< T>());

private IOrderedEnumerable< T> _orderedQueue {获取 {返回 _descending? Queue.OrderByDescending(_orderFunc):Queue.OrderBy(_orderFunc); }

私人列表< T>队列{获取 { return _queue.Value; }

private readonly Func< T,IComparable> _orderFunc;
private readonly bool _descending ;

public OrderedQueue(Func< T,IComparable> orderFunc, bool @descending = false
{
_orderFunc = orderFunc;
_descending = 降序;
}

public void 入队(T项)
{
Queue.Add(item);
_waitForItems.Set();
}


public void Enqueue(IEnumerable< ; T>项目)
{
if (items!= null & & items.Any())
{
Queue.AddRange(items);
_waitForItems.Set();
}
}

public T Dequeue()
{
T result = Peek ();

Queue.Remove(result);

返回结果;
}

public T Peek()
{
return _orderedQueue.FirstOrDefault();
}

ManualResetEvent _waitForItems = new ManualResetEvent( false );

private bool WaitForItems()
{
if (!Queue.Any())
{
_waitForItems = new ManualResetEvent ( false );
_waitForItems.WaitOne();
}
return Queue.Any();
}

public IEnumerable< T> StreamQueue()
{
while (!_ cancel)
while (WaitForItems())
{
if (!_ cancel)
yield return Dequeue();
}
}

private bool _cancel;

public void StopStream()
{
_cancel = true ;
_waitForItems.Set();
}
}
}

解决方案

这种实现效率非常低,而且在线程方面。



很抱歉没有给你全面的建议,但我可以给你一些论据来说服你从头开始这项工作,而不是修理你的课程。我将为您提供有关线程的详细建议以及订购时的基本想法。



不幸的是,您没有清楚地解释您想要实现的目标,但是Tomas Takac建议它将成为一个封锁集合。请参阅我的阻塞队列的实现,其主要与 BlockingCollection 相同,但是当我没有这个.NET FCL类时实现了。无论如何,您可以看到实现更简单并且工作正常:用于线程通信和线程间调用的简单阻塞队列 [ ^ ]。



我没有详细分析你的等待是如何工作的,但仅仅是事实你创建了一个全新的 ManualResetEvent 的实例,每次都表明它无法工作。



现在,这是我的订购反馈。 这不是一个有序的集合。这是每次获取实例时重新排序的集合。真实有序集合是将新项目插入已订购集合中的集合,与更新集合保持订购的方式相同。与每次重新排序相比,你能看出这种行为有多高效吗?您可以考虑使用其中一个可用的有序集合,或者为单个项目实现自己的插入算法。



-SA

Hi
I am trying to create an ordered queue. I have been having an issue where my messages have not been parsed in the correct order because so many are due at the same time.

I could have just made sure that I ordered the list first, but if an urgent message came in then that should skip the queue I have already loaded.

So I made my own orderedQueue. I kept in generic enough that I can use it elsewhere. The SteamQueue() method is useful for Reactive Extension.

This queue is already the major bottleneck in my system so please could I get some feedback on how efficient it is, or if there is a way to make it more so.

Thanks ^_^

Here it is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Tools
{
    public class OrderedQueue<T>
    {
        private readonly Lazy<List<T>> _queue = new Lazy<List<T>>(()=>new List<T>());

        private IOrderedEnumerable<T> _orderedQueue { get { return _descending ? Queue.OrderByDescending(_orderFunc) : Queue.OrderBy(_orderFunc); } }

        private List<T> Queue { get { return _queue.Value; } } 

        private readonly Func<T, IComparable> _orderFunc;
        private readonly bool _descending;

        public OrderedQueue(Func<T, IComparable> orderFunc, bool @descending = false)
        {
            _orderFunc = orderFunc;
            _descending = descending;
        }

        public void Enqueue(T item)
        {
            Queue.Add(item);
            _waitForItems.Set();
        }


        public void Enqueue(IEnumerable<T> items)
        {
            if (items != null && items.Any())
            {
                Queue.AddRange(items);
                _waitForItems.Set();
            }
        }

        public T Dequeue()
        {
            T result = Peek();

            Queue.Remove(result);

            return result;
        }

        public T Peek()
        {
            return _orderedQueue.FirstOrDefault();
        }

         ManualResetEvent _waitForItems = new ManualResetEvent(false);

        private bool WaitForItems()
        {
            if (!Queue.Any())
            {
                _waitForItems = new ManualResetEvent(false);
                _waitForItems.WaitOne();
            }
            return Queue.Any();
        }

        public IEnumerable<T> StreamQueue()
        {
            while(!_cancel)
                while (WaitForItems())
                {
                    if(!_cancel)
                        yield return Dequeue();
                }
        }

        private bool _cancel;

        public void StopStream ()
        {
            _cancel = true;
            _waitForItems.Set();
        }
    }
}

解决方案

This implementation is extremely inefficient and is hardly correct in the threading aspects.

Sorry for not giving you a comprehensive advise, but I can give you the arguments to convince you to start this work from scratch, instead of fixing your class. I'll provide you my detail suggestion on threading and just a basic idea on ordering.

Unfortunately, you did not clearly explain what you wanted to achieve, but Tomas Takac suggested that it's going to be a blocking collection. Please see the implementation of my blocking queue which majorly does the same as BlockingCollection, but was implemented when I did not have this .NET FCL class. Anyway, you can see that the implementation is much simpler and does work correctly: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

I did not analyze in detail how your waiting works, but the mere fact that you create a fresh new instance of ManualResetEvent each time suggests that it cannot work.

Now, here is my feedback on ordering. This is not an ordered collection at all. This is the collection which is reordered every time you get its instance. The real ordered collection is the collection which insert a new item into an already ordered collection the way the updated collection remains ordering. Can you see how much more efficient this behavior can be, compared to re-ordering each time? You can think of using one of the available ordered collections, or implement your own insertion algorithm for a single item.

—SA


这篇关于我可以得到一些反馈(这是一个足够好的问题吗?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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