开发者

How to run lengthy tasks from an ASP.NET page?

开发者 https://www.devze.com 2023-02-11 17:00 出处:网络
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

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
0

精彩评论

暂无评论...
验证码 换一张
取 消