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;
}
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 onIRatesService
(singelton).
IRatesService
depens onIRatesQueueDispatcher
.
holdsratesCache
dictionary. and in its constructor calls toRunDispatcher(_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:
I need to know if the worker failed from its internal reason.
It seems to me that the main purpose of the
HostingEnvironment.QueueBackgroundWorkItem
is to promise the finish of the running task beforeapplication_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 theHandleRunningTaskTermination()
to recycle the application by invokeSystem.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
|
show 4 more comments
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 onIRatesService
(singelton).
IRatesService
depens onIRatesQueueDispatcher
.
holdsratesCache
dictionary. and in its constructor calls toRunDispatcher(_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:
I need to know if the worker failed from its internal reason.
It seems to me that the main purpose of the
HostingEnvironment.QueueBackgroundWorkItem
is to promise the finish of the running task beforeapplication_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 theHandleRunningTaskTermination()
to recycle the application by invokeSystem.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
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 WCFGetRate()
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 usingnew Task(() => Endlessloop(), TaskCreationOptions.LongRunning)
. This creates a dedicated thread for the task.
– Nick
Nov 28 '18 at 9:24
|
show 4 more comments
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 onIRatesService
(singelton).
IRatesService
depens onIRatesQueueDispatcher
.
holdsratesCache
dictionary. and in its constructor calls toRunDispatcher(_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:
I need to know if the worker failed from its internal reason.
It seems to me that the main purpose of the
HostingEnvironment.QueueBackgroundWorkItem
is to promise the finish of the running task beforeapplication_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 theHandleRunningTaskTermination()
to recycle the application by invokeSystem.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
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 onIRatesService
(singelton).
IRatesService
depens onIRatesQueueDispatcher
.
holdsratesCache
dictionary. and in its constructor calls toRunDispatcher(_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:
I need to know if the worker failed from its internal reason.
It seems to me that the main purpose of the
HostingEnvironment.QueueBackgroundWorkItem
is to promise the finish of the running task beforeapplication_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 theHandleRunningTaskTermination()
to recycle the application by invokeSystem.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
c# multithreading wcf task-parallel-library backgroundworker
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 WCFGetRate()
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 usingnew Task(() => Endlessloop(), TaskCreationOptions.LongRunning)
. This creates a dedicated thread for the task.
– Nick
Nov 28 '18 at 9:24
|
show 4 more comments
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 WCFGetRate()
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 usingnew 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
|
show 4 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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