取消当前的同步请求处理 [英] Cancel current synchronous request processing

查看:94
本文介绍了取消当前的同步请求处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试取消用户当前发出的请求。 Web Forms Web App具有导出到excel功能。如果生成Excel报告的时间很长,用户可以取消请求。

I am trying to cancel current request made by user. Web Forms Web App have export to excel feature. If it takes long time to generate excel report user can cancel the request.

单击取消按钮后,服务器应停止处理以节省宝贵的带宽。

Once the cancel button is clicked the server should stop processing to save precious bandwidth.

我找到了以下两种解决方案。

I have found two solutions as listed below.

第一个解决方案:

通过直接跳转到 Application_EndRequest 事件。

    protected void btnCancel_Click(object sender, EventArgs e)
    {

        if (Response.IsClientConnected)
        {

            HttpContext.Current.ApplicationInstance.CompleteRequest();

        }


    }

第二个解决方案:(使用任务并行库-TPL)

Second Solution: (Using Task Parallel Library - 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 取消的方法。我有几个问题:

In second solution I have used Task Parallel Library (TPL) and registered a callback method on cancellation using CancellationToken. I have few questions:


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

  1. But the callback method is never called when I click cancel button, may I know why ?

使用实体框架我可以取消所有3个 .ToList()语句在命中数据库以获取数据之前。

Using Entity framework can I cancel all 3 .ToList() statements before it hits the database to fetch the data.

我也可以知道,是最好的选择TPL

任何帮助将不胜感激。

推荐答案

我认为您必须在启动Task之前注册回调函数。您的代码必须看起来像这样。

I think you have to register the callbackfunction befor you start the Task. Your Code have to look something like this.

在您的Page_Load方法中,您必须在用户会话中保存CancellationTokenSource。

In you Page_Load method you have to save the CancellationTokenSource in the User session.

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。

You can load the list async. With the Method ToListAsync() and there you can give your canalactiontoken in it.

Microsoft文档

希望对您有帮助吗?

这篇关于取消当前的同步请求处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆