在asp.net网页上完成繁重的任务并报告进度

时间:2018-09-07 09:09:40

标签: c# asp.net task-parallel-library

我有一个带按钮的asp.net网络表单页面,当单击按钮时,应该执行一个Task,我希望任务异步执行,并向{{1 }}(也许以后会使用UI,但现在我们坚持使用该文件)。

ASPX:

File

后面的代码:

<asp:UpdatePanel runat="server" ID="upPage">
    <ContentTemplate>
        <div class="jumbotron">
            <asp:Button runat="server" ID="BtnExecute" CssClass="btn btn-primary btn-lg" Text="Execute Heavy Task" OnClick="BtnExecute_Click" />
            <asp:Label runat="server" ID="LblStatus" Text="Ready...."/>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>

public partial class _Default : Page { public Progress<int> HeavyTaskProgress { get; set; } protected void Page_Load(object sender, EventArgs e) { } protected void BtnExecute_Click(object sender, EventArgs e) { HeavyTaskProgress = new Progress<int>(); HeavyTaskProgress.ProgressChanged += Progress_ProgressChanged; Task.Run(() => DoProcessing(HeavyTaskProgress)).ContinueWith(t => ProcessingFinished(t)); LblStatus.Text = "Task is launched.... Please wait"; } private void Progress_ProgressChanged(object sender, int e) { string message = string.Format("progress at {0}%{1}", e, Environment.NewLine); System.IO.File.AppendAllText(@"d:\progress.txt", message); } private void DoProcessing(IProgress<int> progress) { for (int i = 0; i < 10; ++i) { Thread.Sleep(1000); // CPU-bound work if (progress != null) progress.Report(i); } } private void ProcessingFinished(Task t) { System.IO.File.AppendAllText(@"d:\progress.txt", "Task done !! " + t.Status); } } 文件中,我只有一行(任务已完成...),并且未报告进度(d:\progress.txt中的断点未中断)。我认为这可能是由于Progress_ProgressChangedProgress_ProgressChanged在不同的线程中执行而导致的,但我不知道如何解决它。

谢谢您的帮助。

1 个答案:

答案 0 :(得分:3)

我认为您的问题是引发事件时终止处理HTTP请求的线程。
  属于该事件的对象位于呈现页面的线程中。将HTTP响应发送回浏览器后,该线程将终止。因此,当事件引发时,不再有订阅者。
  因为您必须在任务完成之前发送HTTP响应,除非用户必须等待任务完成才能获得一些反馈,所以您应该执行操作以将进度写入任务线程中的文件中。
  如果您希望向用户发送一些常规反馈,可以查看SignalR。
这是将编写进度代码嵌入到任务中的示例:

public class DoingProcessing
{
    public Progress<int> HeavyTaskProgress { get; set; }

    private void Progress_ProgressChanged(object sender, int e)
    {
        string message = string.Format("progress at {0}%{1}", e, Environment.NewLine);
        System.IO.File.AppendAllText(@"d:\progress.txt", message);
    }

    public void DoProcessing()
    {
        HeavyTaskProgress = new Progress<int>();
        HeavyTaskProgress.ProgressChanged += Progress_ProgressChanged;
        DoProcessing(HeavyTaskProgress);
    }
    private void DoProcessing(IProgress<int> progress)
    {
        for (int i = 1; i <= 10; ++i)
        {
            Thread.Sleep(1000); // CPU-bound work
            if (progress != null)
                progress.Report(i*10);
        }
    }

    public void ProcessingFinished(Task t)
    {
        System.IO.File.AppendAllText(@"d:\progress.txt", "Task done !! " + t.Status);
    }
    public DoingProcessing()
    {

    }
}