带事件通知的任务 - .net 4

Zen*_*ker 5 .net c# multithreading task-parallel-library

昨天在SO上,我看到一个线程要求代码,其中一些是这样做的.我的意思是,您(经理线程)使用TPL API启动任务数量,一旦完成作业,该线程应通知您(经理)回复谁维护任务池.

所以这是我试过的代码.虽然我必须说它的工作原理如上所述.

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);            
    }
}
Run Code Online (Sandbox Code Playgroud)

几个抬头:

  1. 不要担心不维护Task []而不是列表然后转换为数组.它只是一个代码.不是说我专注于效率.
  2. 我不担心现在的自定义Dispose实现.

现在我问自己几个问题,但没有说服自己一个合适的答案.他们是:

  1. 这样解决问题的方法好吗?或者有更好的方法吗?代码请:)
  2. 如何确保任务对象真正处理(在调用Dispose时)但不实现自定义Dispose模式.
  3. 没有使用工具进行任何内存泄漏测试.但只是视觉上的缘故,你看到泄漏吗?
  4. 在for循环(main方法)中,我创建的TaskJob类对象是循环的本地对象.因此,这些对象在循环完成后得到gc'd(假设超出范围).那么,事件是如何被回击的,我正在使用这个对象挂钩,但它实际上是在事件被触发后被循环处理.
  5. 还有其他你想添加的东西吗?

非常感谢 :)

Jon*_*eet 22

完全没有必要自己这样做 - 使用Task.ContinueWith或继续使用Task<T>.ContinueWith.这基本上可以让你说出任务完成时要做什么 - 包括在失败,取消和成功时执行不同的代码.

它还会返回一个任务,因此您可以在完成任务后继续执行.

哦,你可以给它一个TaskScheduler,所以从UI线程你可以说,"当这个后台任务完成时,在UI线程上执行给定的委托"或类似的东西.

这是构建C#5异步方法的方法.