Как можно остановить средство чтения запросов в BackgroundWorker? - PullRequest
0 голосов
/ 10 октября 2019

Я начинаю работать с BackgroundWorker , чтобы попробовать его, и мне интересно, как я могу остановить запрос, который возвращает Объект Список и это может занять некоторое время.

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

Вот пример кода с моим BackgroudnWorker и пример запроса:

public partial class Form1 : Form
{
    private BackgroundWorker worker;

    public Form1 (Point location)
    {
        this.Location = location;
        InitializeComponent();
        worker = new BackgroundWorker
        {
            WorkerSupportsCancellation = true,
        };
        worker.DoWork += this.Worker_DoWork;
        worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
    }

    #region Form
    private void ButtonBack_Click (object sender, EventArgs e)
    {
        if (worker.IsBusy && !worker.CancellationPending)
        {
            worker.CancelAsync();
        }
        this.Close();
    }

    private void TextBoxSearch_TextChanged (object sender, EventArgs e)
    {
        while (worker.IsBusy)
        {
            if (worker.IsBusy && !worker.CancellationPending)
            {
                worker.CancelAsync();
            }
        }

        worker.RunWorkerAsync();
    }
    #endregion

    #region Worker
    private void Worker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            if (worker.IsBusy && !worker.CancellationPending)
            {
                worker.CancelAsync();
            }

            Console.WriteLine(e.Error.Message);
        }
    }

    private void Worker_DoWork (object sender, DoWorkEventArgs e)
    {
        if (!worker.CancellationPending)
        {
            // Where I'd like to cut the IEnumerable if worker.CancellationPending to shorten time of process
            foreach (LigneHS ligne in GetLignesHS(worker.CancellationPending))
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                // Do work
            }
        }
        else
        {
            e.Cancel = true;
            return;
        }
    }
    #endregion

     // Sample query
    internal static IEnumerable<LigneHS> GetLignesHS (bool cancellationPending)
    {
        string requete = "SELECT * FROM [MY_TABLE] ORDER BY [date] DESC";
        SqlConnection conn = BDD.OpenBDD16();
        SqlCommand command = new SqlCommand(requete, conn);

        List<LigneHS> lignes = new List<LigneHS>();
        LigneHS ligne = new LigneHS();

        try
        {
            if (!cancellationPending)
            {
                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read() && !cancellationPending)
                {
                    ligne = new LigneHS();

                    if (reader["id"] != DBNull.Value)
                    {
                        ligne.Id = Convert.ToInt32(reader["id"]);

                        // filtering null values for every column

                        lignes.add(ligne);

                        // tried to add the yield return here, but can't inside a try-catch
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("GetLignesHS : " + ex.Message);
        }
        finally
        {
            command.Dispose();
            conn.Close();
        }

        return lignes;
    }
}

Как и здесь, cancellationPending запроса не обновляется, еслирабочего просят остановиться.

Сначала я подумал об использовании yield return для прерывания foreach, если BackgroundWorker попросили остановить. Но я использую try-catch при обработке запроса, поэтому не могу.

Я знаю, что использование CancellationToken , как я делал, когда использовал прямой поток, будетработать, но мне интересно, если это лучший способ добиться того, чего я хочу здесь.

...