Использование потоков в C # winform Solution, но это не прерывание - PullRequest
0 голосов
/ 14 октября 2018

Я использую поток для нескольких задач в решении winform, пытаюсь прервать поток во время его работы, но не прерывать, вот, есть ли какое-то решение для этой ситуации?нужно сделать так, чтобы поток прерывался / выходился гладко, без проблем!

Также есть ли идеи, как я могу сделать приостановку / возобновление потока?

Заранее спасибо!

Thread CommentingThread;
     CommentingThread = new Thread(async () =>
    {

        AddLog("Commenting process has been started!");

        if (CommentBTN.InvokeRequired)
        {
            CommentBTN.Invoke((MethodInvoker)delegate () {




                CommentBTN.Text = "Stop"; });
        }
        else
        {
            CommentBTN.Text = "Stop";
        }

        if (UrlListview.InvokeRequired)

        {

            if (UrlListview.InvokeRequired)
            {
                UrlListview.Invoke((MethodInvoker)async delegate ()
                {



                    foreach (ListViewItem item in UrlListview.Items)
                    {
                        XtraMessageBox.Show(item.Text);
                        int timetodelay = RandomNumber.Next(int.Parse(CommentsMinDelayNumric.Value.ToString()), int.Parse(CommentsMaxDelayNumric.Value.ToString()));
                        await Task.Run(async () =>
                        {

                            await Task.Delay(timetodelay * 1000);

                        });

                    }
                    CommentBTN.Text = "Start";
                    AddLog("Commenting process has been finished sucessfully!");

                });
            }



        }
        else
        {
            foreach (ListViewItem item in UrlListview.Items)
            {
                XtraMessageBox.Show(item.Text);
                int timetodelay = RandomNumber.Next(int.Parse(CommentsMinDelayNumric.Value.ToString()), int.Parse(CommentsMaxDelayNumric.Value.ToString()));
                await Task.Run(async () =>
                {

                    await Task.Delay(timetodelay * 1000 );

                });

            }

                CommentBTN.Text = "Start";
            AddLog("Commenting process has been finished sucessfully!");



        }






        #endregion
    });
    CommentingThread.Start();

    if (CommentBTN.Text == "Stop")
    {
        CommentBTN.Text = "Start";
        CommentingThread.Abort();

        AddLog("Commenting process has been stopped!");


    }

1 Ответ

0 голосов
/ 14 октября 2018

Прежде всего, глядя на ваш код, кажется, что поток может немедленно остановиться, если UrlListview.Items не содержит никаких элементов.В этом случае вы можете пропустить цикл while.

В связи с проблемой остановки потока: вызов CommentingThread.Abort() вызовет ThreadAbortException, что фактически приводит к сбою потока (см. Документы Microsoft для получения дополнительной информации).info для получения дополнительной информации. Чтобы корректно завершить поток, вы должны либо объявить CancellationTokenSource, либо логическое значение, которое может быть установлено в true (или false, в зависимости от вашей реализации), чтобы уведомить поток о том, что ему нужнобыть остановленным. Вот пример:

var myThread_ctoks = new CancellationTokenSource();
Thread myThread = new Thread( async () =>
{
    while (!myThread_ctoks.IsCancellationRequested) // simulate many long actions
    {
        await Task.Delay(TimeSpan.FromSeconds(2));
        Console.WriteLine("Iteration finished!");
    }
});
myThread.Start();  // start the thread

await Task.Delay(TimeSpan.FromMinutes(1));  // lets do some other work
myThread_ctoks.Cancel(); // and now shut down the thread

Этот поток проверяет каждые 2 секунды, требуется ли завершение работы (потому что моделируемое действие занимает столько времени). Как только запрашивается отмена (myThread_ctoks.IsCancellationRequested установленв true) условие while будет ложным и, таким образом, поток завершится. Преимущество выполнения этого способа заключается в том, что поток будет отключен безопасным, определенным образом, поскольку он фактически корректно завершает работу и не падает.

Относительно того, как вы можете приостановить и возобновить поток. Вы также можете использоватьпеременная для управления этим, просто проверяя, разрешено ли потоку выполнять работу или нет.Если он остановится, вы просто подождите секунду в цикле while.

Также есть возможность использовать Thread.Suspend() и Thread.Resume().Однако, согласно Microsoft , существует вероятность, что вы можете заблокировать другие потоки при определенных обстоятельствах.Кроме того, вы не знаете точно, какой код выполняется, когда вы его прерываете.Что может привести к дальнейшему неожиданному поведению.Вот почему я думаю, что лучше всего использовать переменную для управления поведением потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...