任务与事件通知 - .NET 4任务、事件、通知、NET

2023-09-03 07:13:27 作者:智商不在服务区

昨天在于是,我看到了一个线程,要求一个code一些什么呢这种方式。我的意思是,使用第三方物流的API的任务,你(经理线程),起始号码,一旦他们完成作业,该线程需要通知您(经理)回谁维护任务游泳池。

Yesterday on SO, i saw a thread asking for a code which some what does this way. I mean, you (manager thread) start number of tasks using TPL APIs and once they are completed job, that thread should notify you (Manager) back who maintains Task pool.

因此​​,这里是code,我试过。但我必须说,它的工作原理就像我上面描述。

So here is the code which i tried. Although i must say it works as i describe above.

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);            
    }
}

夫妇的抬起头:

Couple of heads up:

不要担心没有维护任务[],而不是一个列表,然后转换为数组。它只是一个code。这并不是说我是专注于效率。 一点也不担心自定义处置执行情况的了。

现在我问自己几个问题,但未能说服自己有合适的答案。在这里,他们是:

Now i am asking myself couple of questions, but fail to convince myself with an suitable answer. Here are they:

是这样解决这个问题好不好?还是有更好的方法来做到这一点? code请:) 如何确保该任务的对象是真正处理(在调用Dispose),但不执行自定义Dispose模式。 有没有做使用工具的任何内存泄漏检测。但就视觉的缘故,你看到泄漏? 在for循环(main方法),我创建这是本地循环TaskJob类对象。因此,这些对象被gc'd(可以说超出了范围)循环结束后。那么,如何在事件被触发回该我钩住使用该对象,但它已被释放时,实际上是事件被触发循环之后。 在任何别的东西要补充的吗?

非常感谢:)

推荐答案

有没有必要自己做的一切 - 使用连续使用的 Task.ContinueWith 或Task<T>.ContinueWith.这基本上让你说一个任务完成时该怎么做 - 包括失败,取消,并成功执行不同的code

There's no need to do this yourself at all - use continuations with Task.ContinueWith or Task<T>.ContinueWith. That basically lets you say what to do when a task completes - including executing different code on failure, cancellation, and success.

此外,它的返回的任务,这样的话就可以继续当这样完成等。

It also returns a task, so you can then continue when that's completed etc.

哦,你可以给它一个的TaskScheduler ,以便从UI线程,你可以说,当后台任务完成后,执行给定的委托上的用户界面线或类似的东西。

Oh, and you can give it a TaskScheduler, so that from a UI thread you can say, "When this background task finishes, execute the given delegate on the UI thread" or similar things.

这是C#5异步方法是建立在方法。

This is the approach that C# 5 async methods are built on.