是否可以将事件(或委托)添加到列表中,以便稍后可以提高偶数;就像能够缓存raise事件以将其推迟到以后再使用(例如缓冲事件)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DelegateQueue {
class Program {
delegate void SomeTimeLaterDelegate(int myValue);
static event SomeTimeLaterDelegate SomeTimeLater;
static void Main(string[] args) {
SomeTimeLater += new SomeTimeLaterDelegate(AnswerAnotherDay);
SomeTimeLater += new SomeTimeLaterDelegate(ItIsPossible);
SomeTimeLater += new SomeTimeLaterDelegate(HenceTheNeed);
List<Delegate> delegates = new List<Delegate>();
SomeTimeLater.Invoke(100); // <== I need to trap this call in a list that I can invoke later.
///both the function call and the value that I'm passing.
///the problem is that there are lots of different events and they must be invoked in the order
///that they occoured (i.e. no skipping in the buffer)
}
static void AnswerAnotherDay(int howManyDays) {
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
static void ItIsPossible(int numberOfPossibilities) {
///that there is in invocation list for the event
///which means that I would have to call each function in that list and pass them the value
}
static void HenceTheNeed(int needs) {
///hence the need to queue the Invocation of the event to a later point
}
}
}
该事件可能有多个订阅者,因此需要从发布者方面而不是订阅者方面进行缓冲。
答案 0 :(得分:1)
这是您所描述内容的字面示例:
class Program
{
delegate void SomeTimeLaterDelegate(int myValue);
delegate void SayHelloDelegate(string name);
static event SomeTimeLaterDelegate SomeTimeLaterEvent;
static event SayHelloDelegate SayHelloLaterEvent;
static void Main(string[] args)
{
SomeTimeLaterEvent += new SomeTimeLaterDelegate(AnswerAnotherDay);
SayHelloLaterEvent += new SayHelloDelegate(SayHello);
var eventsToRaise = new Queue<Action>();
eventsToRaise.Enqueue(() => SomeTimeLaterEvent.Invoke(100));
eventsToRaise.Enqueue(() => SayHelloLaterEvent.Invoke("Bob"));
eventsToRaise.Enqueue(() => SomeTimeLaterEvent.Invoke(200));
eventsToRaise.Enqueue(() => SayHelloLaterEvent.Invoke("John"));
while (eventsToRaise.Any())
{
var eventToRaise = eventsToRaise.Dequeue();
eventToRaise();
//or eventToRaise.Invoke();
}
Console.ReadLine();
}
static void AnswerAnotherDay(int howManyDays)
{
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name}");
}
}
这是Queue<Delegate>
,而不是Queue<Action>
。 Action
表示调用方法而不传递任何参数或接收返回值。
这听起来违反直觉,因为您正在传递参数。但是您没有将参数传递给动作。您正在从动作主体内部传递参数。
这可能会也可能不会有帮助:
当我们宣布
Action someAction = () => AnswerAnotherDay(5);
这就像声明一个如下所示的方法:
void MyMethod()
{
AnswerAnotherDay(5);
}
该方法调用另一个方法并传递一个参数。但是MyMethod
本身不接受任何参数。当我们像这样声明一个内联方法时,它没有名称,因此也称为 anonymous 方法。
我们还可以声明一个带有参数的动作,像这样:
Action<string> action = (s) => SayHelloLater(s);
action("Bob");
我之所以演示不带参数的Action
是因为您说队列可能需要包含具有不同参数的不同类型的事件。
如果我要使用不同的参数一遍又一遍地调用相同的方法,则将参数放入队列可能更有意义。然后,每次我们从队列中取出参数时,都可以使用下一个参数引发事件。
这里可能是一种简化:也许您正在考虑需要引发事件的情况,但是在此示例中,我们可以在没有事件的情况下做完全相同的事情,并且这有点简单。
我们可以只创建调用方法的操作,而不是定义委托和事件,将某些方法添加为事件处理程序,然后创建引发事件的操作。
class Program
{
static void Main(string[] args)
{
var eventsToRaise = new Queue<Action>();
eventsToRaise.Enqueue(() => AnswerAnotherDay(100));
eventsToRaise.Enqueue(() => SayHello("Bob"));
eventsToRaise.Enqueue(() => AnswerAnotherDay(200));
eventsToRaise.Enqueue(() => SayHello("John"));
while (eventsToRaise.Any())
{
var eventToRaise = eventsToRaise.Dequeue();
eventToRaise();
//or eventToRaise.Invoke();
}
Console.ReadLine();
}
static void AnswerAnotherDay(int howManyDays)
{
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
static void SayHello(string name)
{
Console.WriteLine($"Hello, {name}");
}
}
答案 1 :(得分:0)
这是我要面对的挑战:
delegate void SomeTimeLaterDelegate(int myValue);
static event SomeTimeLaterDelegate SomeTimeLater;
static Queue<int> SomeTimeLaterQueue = new Queue<int>(); // Here we store the event arguments
static async Task Main(string[] args)
{
SomeTimeLater += new SomeTimeLaterDelegate(AnswerAnotherDay); // Subscribe to the event
await Task.Delay(100);
OnSomeTimeLaterDefered(10); // Raise an defered event
await Task.Delay(100);
OnSomeTimeLaterDefered(20); // Raise another defered event
await Task.Delay(100);
OnSomeTimeLaterDefered(30); // Raise a third defered event
await Task.Delay(100);
OnSomeTimeLaterFlush(); // Time to raise the queued events for real!
}
static void OnSomeTimeLaterDefered(int value)
{
SomeTimeLaterQueue.Enqueue(value);
}
static void OnSomeTimeLaterFlush()
{
while (SomeTimeLaterQueue.Count > 0)
{
SomeTimeLater?.Invoke(SomeTimeLaterQueue.Dequeue());
}
}
static void AnswerAnotherDay(int howManyDays)
{
Console.WriteLine($"I did this {howManyDays}, later. Hurray for procrastination!");
}
输出:
I did this 10, later. Hurray for procrastination!
I did this 20, later. Hurray for procrastination!
I did this 30, later. Hurray for procrastination!