new Thread()
принимает аргумент ThreadStart (или ParameterisedThreadStart), а ваш обратный вызов DoDelegatedMethod не имеет правильной подписи для ThreadStart.Поэтому вам нужно написать что-то вроде этого:
ThreadStart method = new ThreadStart(() => DoDelegatedMethod(d));
_thread = new Thread(method);
Это создаст анонимный обратный вызов (бит () => DoDelegatedMethod(d)
), который при запуске вызовет DoDelegatedMethod с делегатом d
(который «захватывается»анонимный метод).Теперь вы передаете этот анонимный обратный вызов конструктору Thread, поэтому, когда поток запускается, он вызывает анонимный обратный вызов, который, в свою очередь, вызывает DoDelegatedMethod (d).Эффективно, лямбда адаптирует DoDelegatedMethod к подписи ThreadStart.
Другой способ сделать это - изменить DoDelegatedMethod, чтобы он не принимал аргументы, и сохранить d
в качестве поля члена класса Task, к которому DoDelegateMethod будет обращаться.1010 *
Кроме того, причина, по которой вы получаете ошибку в своем конструкторе, состоит в том, что значения по умолчанию могут иметь только ограниченный набор типов, и делегаты не являются одним из них (только типы, которые разрешены в атрибутах, например, int,long, string и Type разрешены).Вместо этого используйте перегрузку:
public Task() : this(new MyDelegate(DoStuff)) { ... }
public Task(MyDelegate d) { ... }
Обратите внимание, что вы все равно можете получить ошибку, если DoStuff является экземпляром метода Task - это не ясно.Лично я считаю, что наличие делегата по умолчанию для запуска Task
немного странно, поэтому вы можете просто избавиться от конструктора по умолчанию.
После обсуждения в комментариях яЯ подумал, что стоит обобщить предлагаемые изменения в классе Task:
public class Task
{
private readonly Action _action;
// other members as before
// default constructor removed
public Task(Action action)
{
_action = action;
}
public void Start()
{
ThreadStart ts = new ThreadStart(DoDelegatedMethod);
_thread = new Thread(ts);
_thread.Start();
}
private void DoDelegatedMethod()
{
do
{
_action();
}
while (!_shutdownFlag.WaitOne(0));
}
// other members as before
}
И использование:
Task task = new Task(this.AutomatedTasks);
task.Start();
private void AutomatedTasks() { ... }