Передать делегат вместе с параметром в функцию - PullRequest
2 голосов
/ 11 февраля 2012

Я хочу поставить в очередь список задач, а затем выполнить по определенному событию.Код:

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).У меня вопрос, как передать параметр в каждую задачу для очереди задач?

Ответы [ 2 ]

4 голосов
/ 11 февраля 2012

Хорошо, теперь у нас есть немного больше информации, похоже, ваш EnqueueTask метод должен выглядеть следующим образом:

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

правый

Для стартеров Я бы не стал использовать имя Task, которое уже является частью ядра .NET 4 и станет очень выдающимся в .NET 5. Как и Джошуа сказал, что вы в основном получили Func<object[], bool>.

Далее, вы можете сохранить два списка - один для делегатов и один для значений, но проще просто сохранить Queue<Func<bool>> следующим образом:

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


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

Тогда остальная часть вашего кода будет работать "как есть". Лямбда-выражение там будет захватывать values и task, поэтому, когда вы вызываете Func<bool>, оно передает эти значения исходному делегату.

1 голос
/ 11 февраля 2012

При условии правильного понимания вашего вопроса вы просто передаете информацию, как обычный звонок. Вы рассматривали возможность использования Func? Вы можете просто передать аргументы Task.Invoke, т.е. Task.Invoke([arguments here as a *single* object array]).

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;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...