How to run lengthy tasks from an ASP.NET page?
I've got an ASP.NET page with a simple form. The user fills out the form wi开发者_StackOverflow中文版th some details, uploads a document, and some processing of the file then needs to happens on the server side.
My question is - what's the best approach to handling the server side processing of the files? The processing involves calling an exe. Should I use seperate threads for this?
Ideally I want the user to submit the form without the web page just hanging there while the processing takes place.
I've tried this code but my task never runs on the server:
Action<object> action = (object obj) =>
{
// Create a .xdu file for this job
string xduFile = launcher.CreateSingleJobBatchFile(LanguagePair, SourceFileLocation);
// Launch the job
launcher.ProcessJob(xduFile);
};
Task job = new Task(action, "test");
job.Start();
Any suggestions are appreciated.
You could invoke the processing functionality asynchronously in a classic fire and forget fashion:
In .NET 4.0 you should do this using the new Task Parallel Library:
Task.Factory.StartNew(() =>
{
// Do work
});
If you need to pass an argument to the action delegate you could do it like this:
Action<object> task = args =>
{
// Do work with args
};
Task.Factory.StartNew(task, "SomeArgument");
In .NET 3.5 and earlier you would instead do it this way:
ThreadPool.QueueUserWorkItem(args =>
{
// Do work
});
Related resources:
- Task Class
- ThreadPool.QueueUserWorkItem Method
Use:
ThreadPool.QueueUserWorkItem(o => MyFunc(arg0, arg1, ...));
Where MyFunc() does the server-side processing in the background after the user submits the page;
I have a site that does some potentially long running stuff that needs to be responsive and update a timer for the user.
My solution was to build a state machine into the page with a hidden value and some session values.
I have these on my aspx side:
<asp:Timer ID="Timer1" runat="server" Interval="1600" />
<asp:HiddenField runat="server" ID="hdnASynchStatus" Value="" />
And my code looks something like:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
PostbackStateEngineStep()
UpdateElapsedTime()
End Sub
Private Sub PostbackStateEngineStep()
If hdnASynchStatus.Value = "" And Not CBool(Session("WaitingForCallback")) Then
Dim i As IAsyncResult = {...run something that spawns in it's own thread, and calls ProcessCallBack when it's done...}
Session.Add("WaitingForCallback", True)
Session.Add("InvokeTime", DateTime.Now)
hdnASynchStatus.Value = "WaitingForCallback"
ElseIf CBool(Session("WaitingForCallback")) Then
If Not CBool(Session("ProcessComplete")) Then
hdnASynchStatus.Value = "WaitingForCallback"
Else
'ALL DONE HERE
'redirect to the next page now
response.redirect(...)
End If
Else
hdnASynchStatus.Value = "DoProcessing"
End If
End Sub
Public Sub ProcessCallBack(ByVal ar As IAsyncResult)
Session.Add("ProcessComplete", True)
End Sub
Private Sub UpdateElapsedTime()
'update a label with the elapsed time
End Sub
精彩评论