取消当前同步请求处理



我正在尝试取消用户发出的当前请求。Web窗体Web应用程序具有导出到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 ?
}

在第二个解决方案中,我使用了任务并行库(TPL(,并使用CancellationToken注册了取消时的回调方法。我有几个问题:

  1. 但当我单击取消按钮时,回调方法从未被调用,我知道为什么吗?

  2. 使用Entity framework,我可以在它到达数据库获取数据之前取消所有3个.ToList()语句。

  3. 我还可以知道使用TPL是最好的选择吗?

如有任何帮助,我们将不胜感激。

我认为在启动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(),您可以在其中提供您的Canaactiontoken。

Microsoft文档

我希望这对你有帮助?

最新更新