How to execute long process bases on user input in nopCommerce 4.0

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
5 years ago
Hi,
I have to generate a report based on user input. The problem is this process might take long time (hours), so the only choice is to run it in background where the user can review/download the result later.

The task should be triggered by the user where he should enter the parameters to generate the report, so using the scheduled task does not help.

I tried to execute the process within an action like using Task like follows:


[HttpPost]
public IActionResult Generate(ReportModel report)
{
  try
  {

    Task.Run(() =>
    {
      _reportingService.Generate(report)
    });

    SuccessNotification(string.Format("Generating report has been started."));
  }
  catch (Exception xp)
  {
    ErrorNotification(xp);
  }

  return Generate();
}


But without success, I received this error:
The operation cannot be completed because the DbContext has been disposed.



Any ideas regarding implement this issue in nopCommerce 4.0?

Best,
5 years ago
So you have Schedule tasks that run every so often i.e. Send emails
You could make a new Schedule task that is used to run reports and it runs say every 10 minutes or whenever to check if it needs to do a report

You could use a setting to tell it to generate the report call it Report1.RunNow
The user via the web interface has a button "Run Report" that sets Report1.RunNow = True

The schedule task will run and check this setting

If Report1.RunNow == True
       Set Report1.RunNow = False
       Log a message "Report is running now"
       Run the report
       If no error
           Email message "Report is completed - see attached report"
else
      Do Nothing

You also have the option in Schedule tasks to do a run now for checking purposes.
5 years ago
Thanks Yidna, but this won't help for 2 reasons:

1. The task should be triggered on damned. So, it cannot be scheduled because the user decides when to run it.
2. The task is not static. I mean it does not always do the same job. The user should provides some input parameters (ex: start date, end date, ...)
5 years ago
houmam.wazzeh wrote:
Thanks Yidna, but this won't help for 2 reasons:
1. The task should be triggered on damned. So, it cannot be scheduled because the user decides when to run it.
This is what I suggested, the user clicks a button and it sets the setting Report1.RunNow = True
The rest happens automatically when the Schedule task runs

houmam.wazzeh wrote:

2. The task is not static. I mean it does not always do the same job. The user should provides some input parameters (ex: start date, end date, ...)
You can use other settings to pass parameters

Report1.StartDate
Report1.EndDate
etc

The User enters the field values on the webpage and Clicks the "Run Report" Button
The "Run Report" routine then stores the field values in the Settings
Then prints a message for the user "The report has been Schedule to run with the paramaters entered below"
5 years ago
Thanks Yidna, I just want to mention that I am looking to find a solution outside Scheduled Task because they run inside HTTP context, so, there is a chance to face Request Timeout error if the process exceeds the request limit which is by default 20 min.

In the other hand, the report can be executed several times by several users with several parameters, so, it will be difficult to manage the state of the scheduled task settings as you suggest.

That's why I tried to run it inside a separate thread. Even I'd tried to implement https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1#queued-background-tasks but I faced the error mentioned before:

The operation cannot be completed because the DbContext has been disposed.


Best regards,
5 years ago
Hi
Looks like I had same issue. If you modify nopCommerce sources you can use this solution.
Also in this case you need to use scope factory.
For example:

var process = new Thread(delegate ()
{
using (var scope = _serviceScopeFactory.CreateScope())
{
  var reportingService = scope.ServiceProvider.GetService<IReportingService>();
  reportingService.Generate();
}
});
5 years ago
Alvaar wrote:
Hi
Looks like I had same issue. If you modify nopCommerce sources you can use this solution.
Also in this case you need to use scope factory.
For example:

var process = new Thread(delegate ()
{
using (var scope = _serviceScopeFactory.CreateScope())
{
  var reportingService = scope.ServiceProvider.GetService<IReportingService>();
  reportingService.Generate();
}
});


This is what worked for me
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.