我有一个带按钮的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_ProgressChanged
和Progress_ProgressChanged
在不同的线程中执行而导致的,但我不知道如何解决它。
谢谢您的帮助。
答案 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()
{
}
}