将委托与参数一起传递给函数

发布于 2025-01-04 07:41:45 字数 863 浏览 0 评论 0 原文

我想要将任务列表排入队列,然后执行特定事件。代码:

internal class MyClass
{
    private Queue<Task> m_taskQueue;

    protected MyClass()
    {
        m_taskQueue = new Queue<Task>();
    }

    public delegate bool Task(object[] args);

    public void EnqueueTask(Task task)
    {
        m_taskQueue.Enqueue(task);
    }

    public virtual bool Save()
    {
        // save by processing work queue
        while (m_taskQueue.Count > 0)
        {
            var task = m_taskQueue.Dequeue(); 
            var workItemResult = task.Invoke();

            if (!workItemResult) 
            {
                // give up on a failure
                m_taskQueue.Clear();
                return false;
            }                
        }
        return true;
    }
}

每个委托任务可能有自己的参数列表:Task(object[] args)。我的问题是如何将参数传递给任务队列的每个任务?

I want enqueue a list of tasks and then perform on certain event. Code:

internal class MyClass
{
    private Queue<Task> m_taskQueue;

    protected MyClass()
    {
        m_taskQueue = new Queue<Task>();
    }

    public delegate bool Task(object[] args);

    public void EnqueueTask(Task task)
    {
        m_taskQueue.Enqueue(task);
    }

    public virtual bool Save()
    {
        // save by processing work queue
        while (m_taskQueue.Count > 0)
        {
            var task = m_taskQueue.Dequeue(); 
            var workItemResult = task.Invoke();

            if (!workItemResult) 
            {
                // give up on a failure
                m_taskQueue.Clear();
                return false;
            }                
        }
        return true;
    }
}

Each delegate task may have their own list of parameters: Task(object[] args). My question is how to pass the parameter to each task for the task queue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

顾铮苏瑾 2025-01-11 07:41:45

好的,现在我们有了更多信息,听起来您的 EnqueueTask 方法实际上应该如下所示:

public void EnqueueTask(Task task, object[] values)

对吗?

对于初学者,我会避免使用Task这个名称,它已经是.NET 4核心的一部分,并且将在.NET中非常变得突出5. 正如 Joshua 所说,您基本上已经得到了一个 Func

接下来,您可以保留两个列表 - 一个用于委托,另一个用于值,但仅保留一个 Queue> 会更容易,如下所示:

private readonly Queue<Func<bool>> taskQueue = new Queue<Func<bool>>();


public void EnqueueTask(Task task, object[] values)
{
    taskQueue.Enqueue(() => task(values));
}

然后你的代码的其余部分将真正“按原样”工作。那里的 lambda 表达式将捕获 valuestask,因此当您调用 Func 时,它会将这些值提供给原始委托。

Okay, now we have a bit more information, it sounds like your EnqueueTask method should actually look like this:

public void EnqueueTask(Task task, object[] values)

Right?

For starters I would avoid using the name Task, which is already part of the core of .NET 4 and will become very prominent in .NET 5. As Joshua said, you've basically got a Func<object[], bool>.

Next, you could keep two lists - one for the delegates and one for the values, but it's easier just to keep a Queue<Func<bool>> like this:

private readonly Queue<Func<bool>> taskQueue = new Queue<Func<bool>>();


public void EnqueueTask(Task task, object[] values)
{
    taskQueue.Enqueue(() => task(values));
}

Then the rest of your code will actually work "as is". The lambda expression there will capture values and task, so when you invoke the Func<bool>, it will supply those values to the original delegate.

在你怀里撒娇 2025-01-11 07:41:45

如果正确理解您的问题,您只需像正常通话一样传递信息即可。您考虑过使用 Func 吗?您只需将参数传递给 Task.InvokeTask.Invoke([此处的参数为*单个*对象数组])

object[] arguments = null; // assign arguments to something
var workItemResult = task.Invoke(arguments);

下面是 Func 类型的示例。

internal class MyClass
    {
        private Queue<Func<object[], bool>> m_taskQueue;

        protected MyClass()
        {
            m_taskQueue = new Queue<Func<object[], bool>>();
        }



        public void EnqueueTask(Func<object[], bool> task)
        {
            m_taskQueue.Enqueue(task);
        }

        public virtual bool Save()
        {
            object[] arguments = null; // assign arguments to something
            // save by processing work queue
            while (m_taskQueue.Count > 0)
            {
                var task = m_taskQueue.Dequeue();
                var workItemResult = task(arguments);

                if (!workItemResult)
                {
                    // give up on a failure
                    m_taskQueue.Clear();
                    return false;
                }
            }
            return true;
        }
    }

Provided understanding your question correctly you just pass the information like a normal call. Have you considered using Func? You can just pass arguments to the Task.Invoke i.e. Task.Invoke([arguments here as a *single* object array]).

object[] arguments = null; // assign arguments to something
var workItemResult = task.Invoke(arguments);

Below is an example with the Func type.

internal class MyClass
    {
        private Queue<Func<object[], bool>> m_taskQueue;

        protected MyClass()
        {
            m_taskQueue = new Queue<Func<object[], bool>>();
        }



        public void EnqueueTask(Func<object[], bool> task)
        {
            m_taskQueue.Enqueue(task);
        }

        public virtual bool Save()
        {
            object[] arguments = null; // assign arguments to something
            // save by processing work queue
            while (m_taskQueue.Count > 0)
            {
                var task = m_taskQueue.Dequeue();
                var workItemResult = task(arguments);

                if (!workItemResult)
                {
                    // give up on a failure
                    m_taskQueue.Clear();
                    return false;
                }
            }
            return true;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文