Background value background work with return value

I am switching from Task.Run to Hangfire . In .NET 4.5+, Task.Run can return a Task<TResult> , which allows me to run tasks that return except void . Usually I can wait and get the result of my task by accessing the MyReturnedTask.Result property

An example of my old code:

 public void MyMainCode() { List<string> listStr = new List<string>(); listStr.Add("Bob"); listStr.Add("Kate"); listStr.Add("Yaz"); List<Task<string>> listTasks = new List<Task<string>>(); foreach(string str in listStr) { Task<string> returnedTask = Task.Run(() => GetMyString(str)); listTasks.Add(returnedTask); } foreach(Task<string> task in listTasks) { // using task.Result will cause the code to wait for the task if not yet finished. // Alternatively, you can use Task.WaitAll(listTasks.ToArray()) to wait for all tasks in the list to finish. MyTextBox.Text += task.Result + Environment.NewLine; } } private string GetMyString(string str) { // long execution in order to calculate the returned string return str + "_finished"; } 

As far as I can see on the Quick Start page Hangfire, your main guy is BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget")); perfectly executes the code as a background task, but apparently does not support tasks that have a return value (for example, the code presented above). It is right? if not, how can I configure my code to use Hangfire?

PS I already looked at HostingEnvironment.QueueBackgroundWorkItem ( here ), but apparently it lacks the same functionality (background jobs should be void )

EDIT

As @Dejan explained, the main reason I want to switch to Hangfire is the same reason that .NET people added QueueBackgroundWorkItem in .NET 4.5.2. And that reason is well described in an article by Scott Hanselman about basic tasks in ASP.NET. Therefore, I want to quote an article:

QBWI (QueueBackgroundWorkItem) schedules a task that can run in the background, regardless of any request. This differs from a regular ThreadPool work item in that ASP.NET automatically keeps track of the number of registered items through this API that are currently running, and ASP.NET runtime try to delay closing the AppDomain until these run work items are completed.

+8
c # asynchronous hangfire
source share
1 answer

One simple solution would be to poll the monitoring API until the job is completed as follows:

  public static Task Enqueue(Expression<Action> methodCall) { string jobId = BackgroundJob.Enqueue(methodCall); Task checkJobState = Task.Factory.StartNew(() => { while (true) { IMonitoringApi monitoringApi = JobStorage.Current.GetMonitoringApi(); JobDetailsDto jobDetails = monitoringApi.JobDetails(jobId); string currentState = jobDetails.History[0].StateName; if (currentState != "Enqueued" && currentState != "Processing") { break; } Thread.Sleep(100); // adjust to a coarse enough value for your scenario } }); return checkJobState; } 

Attention Of course, in a web hosting scenario, you cannot rely on the continuation of the task ( task.ContinueWith() ) to do more things after completing the task, because AppDomain may be closed - for the same reasons, you probably want to use Hangfire first turn.

+7
source share

All Articles