{"id":6855,"date":"2019-04-06T10:28:37","date_gmt":"2019-04-06T10:28:37","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=6855"},"modified":"2019-04-06T10:28:37","modified_gmt":"2019-04-06T10:28:37","slug":"creating-a-taskscheduler","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/creating-a-taskscheduler\/","title":{"rendered":"Creating a TaskScheduler"},"content":{"rendered":"<p>In my previous post, <a href=\"http:\/\/putridparrot.com\/blog\/executorservice-based-multi-threading-in-java\/\" rel=\"noopener noreferrer\" target=\"_blank\">ExecutorService based multi-threading in Java<\/a>, I looked at the ExectorService which allows us to create our own fixed size threadpool which can, at times, be extremely useful.<\/p>\n<p>As part of a port of some Java code (which used the ExectorService) to C# I had a need for a similar class in .NET and came across the LimitedConcurrencyLevelTaskScheduler which is part of the <a href=\"https:\/\/code.msdn.microsoft.com\/ParExtSamples\" rel=\"noopener noreferrer\" target=\"_blank\">Samples for Parallel Programming with the .NET Framework<\/a>. The code and example of this class can also be found here, <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.threading.tasks.taskscheduler?view=netframework-4.7.2\" rel=\"noopener noreferrer\" target=\"_blank\">TaskScheduler Class<\/a>. <\/p>\n<p>The Task factory&#8217;s StartNew method comes with an overload which takes a TaskScheduler class and this is where the LimitedConcurrencyLevelTaskScheduler is used. For example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar taskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);\r\nvar tsk = Task.Factory.StartNew(() =&gt;\r\n{\r\n   \/\/ do something\r\n}, \r\nCancellationToken.None, \r\nTaskCreationOptions.None, \r\ntaskScheduler);\r\n<\/pre>\n<p>So, if we&#8217;re in a situation where we need to create a new TaskScheduler then we simply implement a TaskScheduler class, here&#8217;s the required overrides.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class MyTaskScheduler : TaskScheduler\r\n{\r\n   protected override IEnumerable&lt;Task&gt; GetScheduledTasks()\r\n   {\r\n   }\r\n\r\n   protected override void QueueTask(Task task)\r\n   {\r\n   }\r\n\r\n   protected override bool TryExecuteTaskInline(\r\n      Task task, bool taskWasPreviouslyQueued)\r\n   {\r\n   }\r\n}\r\n<\/pre>\n<p>The <strong>QueueTask<\/strong> method is called when a Task is added to the scheduler. In the case of an implementation such as LimitedConcurrencyLevelTaskScheduler, this is where we add a task to a queue prior to executing the task.<\/p>\n<p><strong>TryExecuteTaskInline<\/strong> is called when trying to execute a task on the current thread, it&#8217;s passed a Boolean <em>taskWasPreviouslyQueued<\/em> which denotes whether the task has already been queued.<\/p>\n<p><strong>GetScheduledTasks<\/strong> is called to get an enumerable of the tasks currently scheduled within our TaskScheduler.<\/p>\n<p>Optionally, we may wish to override the <strong>MaximumConcurrencyLevel<\/strong> property which stipulates the maximum concurrency level supported (i.e. number of threads), the default is <em>MaxValue<\/em>. Also where we might be maintaining a queue of tasks, we wold want to override the <strong>TryDequeue<\/strong> method for when the scheduler tries to remove a previously scheduled task.<\/p>\n<p>Obviously implementing the TaskScheduler will also require the developer to handle any thread synchronization etc. within the implementation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous post, ExecutorService based multi-threading in Java, I looked at the ExectorService which allows us to create our own fixed size threadpool which can, at times, be extremely useful. As part of a port of some Java code (which used the ExectorService) to C# I had a need for a similar class in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,51],"tags":[],"class_list":["post-6855","post","type-post","status-publish","format-standard","hentry","category-c","category-multi-threading"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/6855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=6855"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/6855\/revisions"}],"predecessor-version":[{"id":6883,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/6855\/revisions\/6883"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=6855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=6855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=6855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}