Вчера на SO я видел поток, спрашивающий код, который кое-что делает таким образом.Я имею в виду, что вы (поток менеджера) запускаете количество задач с помощью API-интерфейсов TPL, и как только они завершают работу, этот поток должен уведомить вас (менеджера) о том, кто поддерживает пул задач.
Так вот код, который я попробовал.Хотя я должен сказать, что это работает так, как я описал выше.
class TaskJob
{
public delegate void NotificationDelegate(int? taskId,string message);
public event NotificationDelegate NotifyCompletion;
public void TaskToRun()
{
try
{
if (Task.CurrentId == 4)//If its a 4th thread, simulate exception
throw new Exception();
Console.WriteLine("Task started with thread id " + Task.CurrentId);
Thread.Sleep(100000);
Console.WriteLine("Task finished with thread id " + Task.CurrentId);
NotifyCompletion(Task.CurrentId, "Successfully completed");
}
catch
{
NotifyCompletion(Task.CurrentId, "Faulted error");
}
}
}
class Program
{
static List<Task> taskList = new List<Task>();
public static void Main()
{
for (int i = 0; i < 5; i++)//starting 5 threads/tasks
{
TaskJob tb = new TaskJob();
tb.NotifyCompletion += new ConsoleApplication1.TaskJob.NotificationDelegate(tb_NotifyCompletion);
Task t = Task.Factory.StartNew(tb.TaskToRun);
taskList.Add(t);
}
Task.WaitAll(taskList.ToArray());
CheckAndDispose();
Console.ReadLine();
}
private static void CheckAndDispose()
{
foreach (var item in taskList)
{
Console.WriteLine("Status of task = " + item.Id + " is = " + item.Status);
item.Dispose();
}
}
static void tb_NotifyCompletion(int? taskId, string message)
{
Console.WriteLine("Task with id completed ="+ taskId + " with message = " + message);
}
}
Пара голов:
- Не беспокойтесь о том, чтобы не поддерживать Task [] вместо того, чтобы иметь список и затем конвертироватьдля массива.Это просто код.Не то чтобы я концентрировался на эффективности.
- На данный момент я не беспокоюсь о собственной реализации Dispose.
Теперь я задаю себе пару вопросов, но не могу убедить себя с помощьюподходящий ответ.Вот они:
- Хороший ли способ решения проблемы?Или есть лучший способ сделать это?Код, пожалуйста:)
- Как убедиться, что объекты задач действительно удаляются (после вызова Dispose), но не реализуют пользовательский шаблон Dispose.
- Не проводилось никакого теста утечки памяти с использованием инструментов.Но только визуально ради, вы видите утечки?
- В цикле for (основной метод) я создаю объекты класса TaskJob, которые являются локальными для цикла.Таким образом, эти объекты получают gc'd (скажем, вне области видимости) после завершения цикла.Итак, как вызывается событие, которое я подключаю с помощью этого объекта, но оно было удалено после цикла, когда на самом деле происходит событие.
- Что-нибудь еще, что вы хотите добавить?
Большое спасибо:)