带事件通知的任务 – .net 4
昨天在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 taskList = new List(); 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循环(main方法)中,我创建的TaskJob类对象是循环的本地对象。 因此,这些对象在循环完成后得到gc’d(假设超出范围)。 那么,事件是如何被回击的,我正在使用这个对象挂钩,但它实际上是在事件被触发后被循环处理。
- 还有其他你想添加的东西吗?
非常感谢 :)
根本没有必要自己这样做 – 使用Task.ContinueWith
或Task
Task.ContinueWith
继续。 这基本上可以让你说出任务完成后该做什么 – 包括在失败,取消和成功时执行不同的代码。
它还返回一个任务,因此您可以在完成任务后继续执行。
哦,你可以给它一个TaskScheduler
,这样你可以从一个UI线程说,“当这个后台任务完成时,在UI线程上执行给定的委托”或类似的东西。
这是构建C#5异步方法的方法。
或者,您可以尝试使用async / await模式。 如果您等待一个任务,这意味着编译器将自动为您生成ContinueWith。
如果使用此模式,则可以编写正常的异步方法,这些方法本身会生成状态机。
检查我的post
http://www.codeproject.com/KB/cs/async.aspx
另一方面,Rx可以表示您的数据流,我的意思是您可以挂钩一系列作业并在Observer上订阅您的observable。
- System.Diaganostics.Process.Id不是任务管理器中显示的相同进程ID。 为什么?
- 处理“动态”音频(C#,WP7)
- 再访问Task.ConfigureAwait(continueOnCapturedContext:false)
- 默认(CancellationToken)如何具有相应的CancellationTokenSource
- 处理WebClient.DownloadString的正确方法的exception
- 如何在C#中增加控制台窗口的大小?
- 如何在XDocument中删除除root之外的节点的xmlns属性
- NHibernate批量插入或更新
- 如何设置pdf页面设置以打印属性对话框?