当前位置:  开发笔记 > 编程语言 > 正文

C#:将对象添加到队列时触发事件

如何解决《C#:将对象添加到队列时触发事件》经验,为你挑选了2个好方法。

我需要能够在将对象添加到a时触发事件Queue.

我创建了一个扩展的新类Queue:

public delegate void ChangedEventHandler(object sender, EventArgs e);

public class QueueWithChange : Queue
{
    public event ChangedEventHandler Changed;

    protected virtual void OnChanged(EventArgs e) {
        if (Changed != null)
        {
            Changed(this, e);
        }
    }
}

然后从另一个类附加事件,如:

QueueWithChange eventQueue = new QueueWithChange();

//

eventQueue.Changed += new ChangedEventHandler(delegate(object s, EventArgs ex) {
    //This event is not being triggered, so this code is unreachable atm...and that is my problem

    if (eventQueue.Count > 0)
    {
        eventQueue.Dequeue().Invoke(new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(5) });
        actionTimer.Stop();
    }
});

但每当我将对象(eventQueue.Enqueue(something))排入队列时,附加事件就不会被触发.

我在这里错过了什么?



1> Marc Gravell..:

如果你的意思是非泛型Queue类,那么你可以覆盖Enqueue:

public override void Enqueue(object obj)
{
    base.Enqueue(obj);
    OnChanged(EventArgs.Empty);
}

但是,如果您指的是泛型Queue类,请注意没有合适的虚拟方法可以覆盖.您可能最好用自己的类封装队列:

(**重要编辑:删除基类!!!**)

class Foo
{
    private readonly Queue queue = new Queue();
    public event EventHandler Changed;
    protected virtual void OnChanged()
    {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public virtual void Enqueue(T item)
    {
        queue.Enqueue(item);
        OnChanged();
    }
    public int Count { get { return queue.Count; } }

    public virtual T Dequeue()
    {
        T item = queue.Dequeue();
        OnChanged();
        return item;        
    }
}

但是,查看代码,您可能在这里使用多个线程.如果是这种情况,请考虑使用线程队列.



2> NovaJoe..:

我只是写了所谓的TriggeredQueue。这启发了马克·格雷夫(Marc Gravell)的答案。

您可以在这里找到我的帖子:http : //joesauve.com/triggeredqueuet

和要点在这里:http : //gist.github.com/jsauve/b2e8496172fdabd370c4

它有四个事件:

威尔入队

威尔·出队

入队

出队

您可以像这样钩住其中的任何一个:

YourQueue.WillEnqueue += (sender, e) => {
    // kick off some process
};
YourQueue.DidEnqueue += (sender, e) => {
    // kick off some process
    // e.Item provides access to the enqueued item, if you like
};
YourQueue.WillDequeue += (sender, e) => {
    // kick off some process
};
YourQueue.DidDequeue += (sender, e) => {
    // kick off some process
    // e.Item provides access to the dequeued item, if you like
};

一个巧妙的技巧是,您可以使用DidDequeue方法启动某个进程,以通过发出Web请求或从文件系统加载某些数据来确保队列已满,等等。我在Xamarin移动应用程序中使用此类来确保数据并且预先缓存了图像以提供流畅的用户体验,而不是在图像滚动到屏幕后再加载图像(就像您可能在Facebook和无数其他应用中看到的那样)。

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有