Отменить обработку синхронного запроса

Я пытаюсь отменить текущий запрос, сделанный пользователем. Веб-приложения Web Forms имеют экспорт в excel. Если для генерации отчета excel требуется много времени, пользователь может отменить запрос.

После нажатия кнопки отмены сервер должен прекратить обработку, чтобы сэкономить драгоценную полосу пропускания.

Я нашел два решения, перечисленные ниже.

Первое решение:

Предотвратите выполнение дополнительного кода, перейдя прямо к Application_EndRequestсобытию.

    protected void btnCancel_Click(object sender, EventArgs e)
    {

        if (Response.IsClientConnected)
        {

            HttpContext.Current.ApplicationInstance.CompleteRequest();

        }


    }

Второе решение: (Использование Task Parallel Library - CancellationTokenSource tokenSource = новый CancellationTokenSource (); защищен недействительным Page_Load ( объект отправителя , EventArgs е ) { } защищены недействительным btnExportExcel_Click ( объект отправителя , EventArgs е ) { CancellationToken cToken = tokenSource . Токен , задачи . Фабрика . StartNew (() => { // делаем тяжелую работу GenerateReport ( sender , cToken ), if ( cToken . IsCancellationRequested ) { // другой поток решил отменить return ; } }, cToken ); // зарегистрировать делегат для обратного вызова, когда запрос аннулирования выполняется cToken . Register (() => cancelNotification ()); } private void GenerateReport ( отправитель объекта , CancellationToken ct ) { var students = _context . Студенты . ToList (); var courses = _context . Курсы . ToList (); var teachers = _context . Учителя . ToList (); // TODO: Используйте выше данных для генерации Excel Report // Просто Имитировать Экспорт преуспеть тему . Сон ( 7000 ); } protected void btnCancel_Click ( отправитель объекта , EventArgs e ) { tokenSource . Отменить (); } private static void cancelNotification () { // Почему не звонил? } )

CancellationToken

Во втором решении я использовал параллельную библиотеку задач (TPL) и зарегистрировал метод обратного вызова при аннулировании Entity framework. У меня мало вопросов:

  1. Но метод обратного вызова никогда не вызывается, когда я нажимаю кнопку отмены, могу я знать, почему?

  2. Использование .ToList()я могу отменить все 3 TPLоператора, прежде чем он попадет в базу данных для извлечения данных.

  3. Также могу ли я знать, с какими наилучшими вариантами TPL?

Любая помощь будет оценена по достоинству.

c#,.net,entity-framework,webforms,task-parallel-library,

0

Ответов: 1


1

Я думаю, вам нужно зарегистрировать функцию callback перед началом задачи. Ваш код должен выглядеть примерно так.

В методе 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 ?

    }
}

Ваш второй вопрос.

Вы можете загрузить список async. С помощью метода ToListAsync()и там вы можете дать свой canalactiontoken в нем.

Документация Microsoft

Надеюсь, это поможет вам?

C # ,. сеть, сущность-рамка, WebForms, задача Параллельной библиотека,
Похожие вопросы