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

问题描述 投票:1回答:1

我有一个带有按钮的asp.net webforms页面,当点击按钮时会有一个应该执行的Task,我希望任务是异步执行的,并且它将进度报告给File(可能稍后会报告给UI,但对于现在我们坚持文件)。

ASPX:

<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_ProgressChanged中的断点没有破坏)。我认为这可能是因为Progress_ProgressChangedDoProcessing在不同的线程中执行但我不知道如何修复它。

谢谢您的帮助。

c# asp.net task-parallel-library
1个回答
3
投票

我认为你的问题是在引发事件时终止处理HTTP请求的线程。 包含在事件中的对象位于呈现页面的线程中。一旦HTTP rsponse被发送回浏览器,该线程就会终止。因此,当事件被提出时,不再有订户。 由于您必须在任务完成之前发送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()
    {

    }
} 
© www.soinside.com 2019 - 2024. All rights reserved.