具有参数的代理队列

时间:2014-05-27 20:39:35

标签: c# delegates queue

这个问题对我来说有点复杂,我不是C#guru。

基本上我有一些我想要处理的任务的队列。我希望能够将各种方法推送到该队列,它们将执行不同的操作,但所有方法都将一个字符串作为参数。问题是:如何通过代表的使用实现这一目标?我不知道怎么做,所以编译器不会抛出任何错误。

或多或少地说明我想要做的事情的代码:

 delegate void Del(string);
 Queue<Del> Q = new Queue<Del>();

 public DT()
 {

        string foo = "bar";


        Q.Enqueue((foo) =>
        {
            //do some stuff
        });

 }
 //somewhere else I constantly check the queue and run the tasks

这种设计可能看起来很奇怪,但在这方面,我确定我在做什么。

因此,这给出了编译器错误,即无法声明局部变量foo。当然我不想声明它,我想将它传递给正在推送队列的函数。我该怎么办?

我希望你理解我的问题。谢谢。

2 个答案:

答案 0 :(得分:3)

只使用不同的lambda参数名称(目前它与本地foo变量声明冲突):

 Q.Enqueue(f => { 
     //do some stuff
 });

然后你可以从队列中获取一个传递参数委托给它:

 Q.Dequeue()(foo);

如果你想捕获foo变量的值,那么只需在做一些东西部分中使用它。在这种情况下,您可能希望委托具有签名,该签名不接受任何输入参数:

 Queue<Action> actions = new Queue<Action>();
 string foo = "bar";
 actions.Enqueue(() => Console.WriteLine(foo));
 actions.Dequeue()();

顺便说一句:您不需要创建这些代表 - 使用现有的Action<T>Action代表。

答案 1 :(得分:2)

委托类型形成最终呼叫的签名。由于您已经说过在对其进行排队时提供了字符串,因此该调用的签名是

delegate void Del();
Queue<Del> Q = new Queue<Del>();

现在加入队列:

public DT()
{
    string foo = "bar";

    Q.Enqueue(() =>
    {
        //do some stuff using foo
    });
}

foo的值在lambda中的范围内,并且在它被入队之前将被捕获到委托中。这称为闭包

请注意,您可以使用预定义的委托类型System.Action,而不是创建自己的委托。