【问题标题】:Doing heavy task and report progress in asp.net web page在 asp.net 网页中执行繁重的任务并报告进度
【发布时间】:2018-09-07 17:49:04
【问题描述】:

我有一个带有按钮的 asp.net 网络表单页面,当单击该按钮时,应该执行一个 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】:

    我认为您的问题是处理 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()
        {
    
        }
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多