2013-07-29 65 views
13

在我的csharp应用程序中,我有某些事件应该触发函数在特定线程上调用,这是通过一些代码循环的。功能集合

现在,而不是手工存储所有这些数据,并有一个大开关的情况下,我想知道是否有可能将这些函数和它们的paramteres存储在列表中,然后由其他线程处理?

伪代码:

var func = pointer2somefunction(13, "abc"); 
list.add(func); 

其他线程:

while (list.Count > 0) 
{ 
    var func = list.Remove(0); 
    func.Invoke(); 
} 
+6

您可以使用C#的函数指针版本[代表](http://msdn.microsoft.com/en-us/library/ms173172.aspx)。 –

+0

无论使用哪种方法,都要确保使用线程安全的'List'来确保线程之间不会出现同步问题。 –

回答

18

是的,你可以通过使用List<Action>或适合在我看来稍好一Queue<Action>做到这一点。 Action是一个无参数无效委托类型:

var functions = new Queue<Action>(); 

functions.Enqueue(() => Console.WriteLine("Foo")); 
functions.Enqueue(() => Console.WriteLine("Bar")); 

while (functions.Any()) 
{ 
    // note the double parenthesis here: one for Dequeue 
    // and one for your dequeued function 
    functions.Dequeue()(); 
} 

如果您需要的参数,使用Action<T>为一体,Action<T, T>两个等等。对于返回值,请使用Func而不是Action(或Func<T>等)。

也许事件也会帮助你。事件是C#的语言功能,使用观察者模式

// events are usually on the instance rather than static 
private static event EventHandler MyEvent; 

static void Main(string[] args) 
{ 
    MyEvent += (s, e) => Console.WriteLine("FooEvent"); 
    MyEvent += (s, e) => Console.WriteLine("BarEvent"); 
    MyEvent(null, EventArgs.Empty); 
} 

事件是多播委托,这是一个委托的功能一个列表。不过,您不能控制每个处理程序的线程:与上面的Queue<Action>不同,您可以在其中启动或重新使用线程,多播委托从外部公开为一个请求,让您只对所有调用使用一个线程。

+4

@clamp请注意,['Action'](http://msdn.microsoft.com/en-us/library/system.action.aspx)只是一个没有参数且没有返回值的函数的预定义类型。如果你想让函数接受参数或者返回一些东西,你仍然可以这样做,类型签名会稍微长一些。 –

1

我认为你正在以这种方式实施活动。您不需要大开关的情况下,您需要几个事件,然后在正确的时间触发正确的事件,并使用正确的方法进行注册。

你可以做一个代表的列表,但是当你需要不同的函数和不同的参数时,它会开始变得复杂。