QueueBackgroundWorkItem vs. Task.Run for background task





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm new to background work (and generally in Task usage) and have a doubts about my implementation.



(Note: If you think it's too long, let me know by comment and I'll shorten it)



Assume a WCF service which returns currencys rates:



[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService



  • The RatesServiceSvc depends on IRatesService(singelton).


  • IRatesService depens on IRatesQueueDispatcher.
    holds ratesCache dictionary. and in its constructor calls to RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);


The internal implementation of the IRatesService is like this: The service instantiate a third party queue which gets from the network the current rates and pushes them as events to the queue (endlessly). In order to fetch the events I need to invoke the IRatesQueueDispatcher.Run(...) that runs backgroun loop:



The IRatesService implementation:



private void RunDispatcher(Queue queue, CancellationTokenSource dispatcherCancellationTokenSource)
{
Task<TaskCompletionCause> dispatcher = Task.Run(() => _queueDispatcher.Run(queue, dispatcherCancellationTokenSource.Token));
dispatcher.ContinueWith((dispatcherTask) =>
{
HandleRunningTaskTermination(dispatcherTask.Result);
});
}


IRatesQueueDispatcher.Run() Imlementation:



while (!cancellationToken.IsCancellationRequested && IsRatesQueueOk(eventsCount))
{
eventsCount = ratesQueueToDispatch.Dispatch();
if (eventsCount < 0)
{
Thread.Sleep(_sleepTimeWhenReutersQueueEmpty);
}
}


The queue.Dispach() call, leads to invoke (in the same thread) to the implementation of EventClient.ProcessEvent(event) (which registered in the initialization phase). The data fetched from the events inserted to the rateCache (in this case it's a ConcurrentDictionary)



The application needs:




  • The background loop will run endlessly.

  • If background loop fails for some reason I need to know it immediately.

  • If application has another issue I need to kill the background task.


The question:
Do my solution of running the backgroun work by Task.Run(...).ContinueWith(...) is Ok? I read in some palces about "Fire and Forget" Dangers (here
and here) also I know .NET 4.5.2 suggests the HostingEnvironment.QueueBackgroundWorkItem



but I'm not sure if it's the appropriate solution for me. Because:




  1. I need to know if the worker failed from its internal reason.


  2. It seems to me that the main purpose of the HostingEnvironment.QueueBackgroundWorkItem is to promise the finish of the running task before application_end. For my needs There isn't meaning of running the background work when application ends, and also vice versa - If background failed there is no meaning of the application to run without it. For that reason I implemented the HandleRunningTaskTermination() to recycle the application by invoke System.Web.HttpRuntime.UnloadAppDomain();.



After all, I'm worried about my implemetation and I'm looking for a better solution. There is better??










share|improve this question

























  • I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

    – Yeldar Kurmangaliyev
    Nov 25 '18 at 11:25













  • @YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

    – Roni
    Nov 25 '18 at 11:42











  • I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

    – Nick
    Nov 26 '18 at 10:04






  • 1





    @Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

    – Nick
    Nov 27 '18 at 15:29






  • 1





    @Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

    – Nick
    Nov 28 '18 at 9:24


















0















I'm new to background work (and generally in Task usage) and have a doubts about my implementation.



(Note: If you think it's too long, let me know by comment and I'll shorten it)



Assume a WCF service which returns currencys rates:



[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService



  • The RatesServiceSvc depends on IRatesService(singelton).


  • IRatesService depens on IRatesQueueDispatcher.
    holds ratesCache dictionary. and in its constructor calls to RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);


The internal implementation of the IRatesService is like this: The service instantiate a third party queue which gets from the network the current rates and pushes them as events to the queue (endlessly). In order to fetch the events I need to invoke the IRatesQueueDispatcher.Run(...) that runs backgroun loop:



The IRatesService implementation:



private void RunDispatcher(Queue queue, CancellationTokenSource dispatcherCancellationTokenSource)
{
Task<TaskCompletionCause> dispatcher = Task.Run(() => _queueDispatcher.Run(queue, dispatcherCancellationTokenSource.Token));
dispatcher.ContinueWith((dispatcherTask) =>
{
HandleRunningTaskTermination(dispatcherTask.Result);
});
}


IRatesQueueDispatcher.Run() Imlementation:



while (!cancellationToken.IsCancellationRequested && IsRatesQueueOk(eventsCount))
{
eventsCount = ratesQueueToDispatch.Dispatch();
if (eventsCount < 0)
{
Thread.Sleep(_sleepTimeWhenReutersQueueEmpty);
}
}


The queue.Dispach() call, leads to invoke (in the same thread) to the implementation of EventClient.ProcessEvent(event) (which registered in the initialization phase). The data fetched from the events inserted to the rateCache (in this case it's a ConcurrentDictionary)



The application needs:




  • The background loop will run endlessly.

  • If background loop fails for some reason I need to know it immediately.

  • If application has another issue I need to kill the background task.


The question:
Do my solution of running the backgroun work by Task.Run(...).ContinueWith(...) is Ok? I read in some palces about "Fire and Forget" Dangers (here
and here) also I know .NET 4.5.2 suggests the HostingEnvironment.QueueBackgroundWorkItem



but I'm not sure if it's the appropriate solution for me. Because:




  1. I need to know if the worker failed from its internal reason.


  2. It seems to me that the main purpose of the HostingEnvironment.QueueBackgroundWorkItem is to promise the finish of the running task before application_end. For my needs There isn't meaning of running the background work when application ends, and also vice versa - If background failed there is no meaning of the application to run without it. For that reason I implemented the HandleRunningTaskTermination() to recycle the application by invoke System.Web.HttpRuntime.UnloadAppDomain();.



After all, I'm worried about my implemetation and I'm looking for a better solution. There is better??










share|improve this question

























  • I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

    – Yeldar Kurmangaliyev
    Nov 25 '18 at 11:25













  • @YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

    – Roni
    Nov 25 '18 at 11:42











  • I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

    – Nick
    Nov 26 '18 at 10:04






  • 1





    @Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

    – Nick
    Nov 27 '18 at 15:29






  • 1





    @Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

    – Nick
    Nov 28 '18 at 9:24














0












0








0








I'm new to background work (and generally in Task usage) and have a doubts about my implementation.



(Note: If you think it's too long, let me know by comment and I'll shorten it)



Assume a WCF service which returns currencys rates:



[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService



  • The RatesServiceSvc depends on IRatesService(singelton).


  • IRatesService depens on IRatesQueueDispatcher.
    holds ratesCache dictionary. and in its constructor calls to RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);


The internal implementation of the IRatesService is like this: The service instantiate a third party queue which gets from the network the current rates and pushes them as events to the queue (endlessly). In order to fetch the events I need to invoke the IRatesQueueDispatcher.Run(...) that runs backgroun loop:



The IRatesService implementation:



private void RunDispatcher(Queue queue, CancellationTokenSource dispatcherCancellationTokenSource)
{
Task<TaskCompletionCause> dispatcher = Task.Run(() => _queueDispatcher.Run(queue, dispatcherCancellationTokenSource.Token));
dispatcher.ContinueWith((dispatcherTask) =>
{
HandleRunningTaskTermination(dispatcherTask.Result);
});
}


IRatesQueueDispatcher.Run() Imlementation:



while (!cancellationToken.IsCancellationRequested && IsRatesQueueOk(eventsCount))
{
eventsCount = ratesQueueToDispatch.Dispatch();
if (eventsCount < 0)
{
Thread.Sleep(_sleepTimeWhenReutersQueueEmpty);
}
}


The queue.Dispach() call, leads to invoke (in the same thread) to the implementation of EventClient.ProcessEvent(event) (which registered in the initialization phase). The data fetched from the events inserted to the rateCache (in this case it's a ConcurrentDictionary)



The application needs:




  • The background loop will run endlessly.

  • If background loop fails for some reason I need to know it immediately.

  • If application has another issue I need to kill the background task.


The question:
Do my solution of running the backgroun work by Task.Run(...).ContinueWith(...) is Ok? I read in some palces about "Fire and Forget" Dangers (here
and here) also I know .NET 4.5.2 suggests the HostingEnvironment.QueueBackgroundWorkItem



but I'm not sure if it's the appropriate solution for me. Because:




  1. I need to know if the worker failed from its internal reason.


  2. It seems to me that the main purpose of the HostingEnvironment.QueueBackgroundWorkItem is to promise the finish of the running task before application_end. For my needs There isn't meaning of running the background work when application ends, and also vice versa - If background failed there is no meaning of the application to run without it. For that reason I implemented the HandleRunningTaskTermination() to recycle the application by invoke System.Web.HttpRuntime.UnloadAppDomain();.



After all, I'm worried about my implemetation and I'm looking for a better solution. There is better??










share|improve this question
















I'm new to background work (and generally in Task usage) and have a doubts about my implementation.



(Note: If you think it's too long, let me know by comment and I'll shorten it)



Assume a WCF service which returns currencys rates:



[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService



  • The RatesServiceSvc depends on IRatesService(singelton).


  • IRatesService depens on IRatesQueueDispatcher.
    holds ratesCache dictionary. and in its constructor calls to RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);


The internal implementation of the IRatesService is like this: The service instantiate a third party queue which gets from the network the current rates and pushes them as events to the queue (endlessly). In order to fetch the events I need to invoke the IRatesQueueDispatcher.Run(...) that runs backgroun loop:



The IRatesService implementation:



private void RunDispatcher(Queue queue, CancellationTokenSource dispatcherCancellationTokenSource)
{
Task<TaskCompletionCause> dispatcher = Task.Run(() => _queueDispatcher.Run(queue, dispatcherCancellationTokenSource.Token));
dispatcher.ContinueWith((dispatcherTask) =>
{
HandleRunningTaskTermination(dispatcherTask.Result);
});
}


IRatesQueueDispatcher.Run() Imlementation:



while (!cancellationToken.IsCancellationRequested && IsRatesQueueOk(eventsCount))
{
eventsCount = ratesQueueToDispatch.Dispatch();
if (eventsCount < 0)
{
Thread.Sleep(_sleepTimeWhenReutersQueueEmpty);
}
}


The queue.Dispach() call, leads to invoke (in the same thread) to the implementation of EventClient.ProcessEvent(event) (which registered in the initialization phase). The data fetched from the events inserted to the rateCache (in this case it's a ConcurrentDictionary)



The application needs:




  • The background loop will run endlessly.

  • If background loop fails for some reason I need to know it immediately.

  • If application has another issue I need to kill the background task.


The question:
Do my solution of running the backgroun work by Task.Run(...).ContinueWith(...) is Ok? I read in some palces about "Fire and Forget" Dangers (here
and here) also I know .NET 4.5.2 suggests the HostingEnvironment.QueueBackgroundWorkItem



but I'm not sure if it's the appropriate solution for me. Because:




  1. I need to know if the worker failed from its internal reason.


  2. It seems to me that the main purpose of the HostingEnvironment.QueueBackgroundWorkItem is to promise the finish of the running task before application_end. For my needs There isn't meaning of running the background work when application ends, and also vice versa - If background failed there is no meaning of the application to run without it. For that reason I implemented the HandleRunningTaskTermination() to recycle the application by invoke System.Web.HttpRuntime.UnloadAppDomain();.



After all, I'm worried about my implemetation and I'm looking for a better solution. There is better??







c# multithreading wcf task-parallel-library backgroundworker






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 '18 at 8:04









Uwe Keim

27.8k32138217




27.8k32138217










asked Nov 25 '18 at 11:18









RoniRoni

80113




80113













  • I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

    – Yeldar Kurmangaliyev
    Nov 25 '18 at 11:25













  • @YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

    – Roni
    Nov 25 '18 at 11:42











  • I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

    – Nick
    Nov 26 '18 at 10:04






  • 1





    @Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

    – Nick
    Nov 27 '18 at 15:29






  • 1





    @Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

    – Nick
    Nov 28 '18 at 9:24



















  • I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

    – Yeldar Kurmangaliyev
    Nov 25 '18 at 11:25













  • @YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

    – Roni
    Nov 25 '18 at 11:42











  • I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

    – Nick
    Nov 26 '18 at 10:04






  • 1





    @Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

    – Nick
    Nov 27 '18 at 15:29






  • 1





    @Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

    – Nick
    Nov 28 '18 at 9:24

















I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

– Yeldar Kurmangaliyev
Nov 25 '18 at 11:25







I didn't read the question yet, but just from the subject - are you sure you want to run infinite task in WCF? I would definitely not do this, because WCF is not designed for this sort of tasks and you probably will bring many problems with it. Instead, you can run your background job as a separate daemon. It can be the same app windows service which hosts your WCF.

– Yeldar Kurmangaliyev
Nov 25 '18 at 11:25















@YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

– Roni
Nov 25 '18 at 11:42





@YeldarKurmangaliyev The WCF service not used to run background work. It uses background work in order to populate the cache with currency data, which in turn will returened in the WCF GetRate() request. In telling this, it seems more reasonable?

– Roni
Nov 25 '18 at 11:42













I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

– Nick
Nov 26 '18 at 10:04





I would create a dedicated service app to run the "endless" loop. You can also implement your WCF service in it. If you need or want to have your WCF service hosted by IIS, then from your WCF service you can call the service app (again via WCF) to send commands and get results. This will enable you to have a proper control over the life of your "endless" loop, restart it, if necessary, and be independent from IIS.

– Nick
Nov 26 '18 at 10:04




1




1





@Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

– Nick
Nov 27 '18 at 15:29





@Roni, Windows Services are stateful, meaning you don't fire-and-forget a long-running background task. You will be able to spawn a thread that lives for the whole life of your Windows Service, which you can initialize and restart if it crashes for some reason.

– Nick
Nov 27 '18 at 15:29




1




1





@Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

– Nick
Nov 28 '18 at 9:24





@Roni, for long-running task you might want to create the task using new Task(() => Endlessloop(), TaskCreationOptions.LongRunning). This creates a dedicated thread for the task.

– Nick
Nov 28 '18 at 9:24












0






active

oldest

votes












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466914%2fqueuebackgroundworkitem-vs-task-run-for-background-task%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466914%2fqueuebackgroundworkitem-vs-task-run-for-background-task%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()