我正在尝试取消用户当前的请求。 Web Forms Web App具有导出到excel功能。如果生成Excel报告的时间很长,则用户可以取消该请求。
单击取消按钮后,服务器应停止处理以节省宝贵的带宽。
我发现了以下两种解决方案。
第一个解决方案:
直接跳转到Application_EndRequest
事件,以防止执行更多代码。
protected void btnCancel_Click(object sender, EventArgs e)
{
if (Response.IsClientConnected)
{
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
第二个解决方案:(使用任务并行库-TPL)
CancellationTokenSource tokenSource = new CancellationTokenSource();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnExportExcel_Click(object sender, EventArgs e)
{
CancellationToken cToken = tokenSource.Token;
Task.Factory.StartNew(() =>
{
// do some heavy work here
GenerateReport(sender, cToken);
if (cToken.IsCancellationRequested)
{
// another thread decided to cancel
return;
}
}, cToken);
// to register a delegate for a callback when a
// cancellation request is made
cToken.Register(() => cancelNotification());
}
private void GenerateReport(object sender, CancellationToken ct)
{
var students = _context.Students.ToList();
var courses = _context.Courses.ToList();
var teachers = _context.Teachers.ToList();
// Todo: Use above data to Generate Excel Report
// Just to Simulate Export to excel
Thread.Sleep(7000);
}
protected void btnCancel_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}
private static void cancelNotification()
{
// Why never called ?
}
在第二个解决方案中,我使用了Task Parallel Library (TPL)并在注销时使用了CancellationToken
注册了一个回调方法。我有几个问题:
但是当我单击取消按钮时,从未调用过回调方法,我知道为什么吗?
我可以使用Entity framework
取消所有3条.ToList()
语句,然后再命中数据库以获取数据。
我也可以知道与TPL
一起使用是最好的选择吗?
任何帮助将不胜感激。
答案 0 :(得分:1)
我认为您必须在启动Task之前注册回调函数。您的代码必须看起来像这样。
在Page_Load方法中,您必须在用户会话中保存CancellationTokenSource。
public partial class Contact : Page
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.Session["Cart"] != null)
{
tokenSource = HttpContext.Current.Session["Cart"] as CancellationTokenSource;
}
else
{
HttpContext.Current.Session.Add("Cart", new CancellationTokenSource());
tokenSource = HttpContext.Current.Session["Cart"] as CancellationTokenSource;
}
}
protected void btnExportExcel_Click(object sender, EventArgs e)
{
CancellationToken cToken = tokenSource.Token;
cToken.Register(() => cancelNotification());
Task.Factory.StartNew(() =>
{
// do some heavy work here
GenerateReport(sender, cToken);
if (cToken.IsCancellationRequested)
{
// another thread decided to cancel
return;
}
}, cToken);
}
private void GenerateReport(object sender, CancellationToken ct)
{
var students = _context.Students.ToList();
var courses = _context.Courses.ToList();
var teachers = _context.Teachers.ToList();
// Todo: Use above data to Generate Excel Report
// Just to Simulate Export to excel
Thread.Sleep(7000);
}
protected void btnCancel_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}
private static void cancelNotification()
{
// Why never called ?
}
}
您的第二个问题。
您可以异步加载列表。使用方法ToListAsync()
,您可以在其中输入canalactiontoken。
希望对您有帮助吗?