С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28

Как кнопкой прервать thread.sleep или await task.delay?

27.03.2021, 09:46. Показов 3736. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C# Windows Forms как кнопкой досрочно прервать thread.sleep или await task.delay? Обновляю бд каждые 10 секунд, если остановить и тут же запустить обновление, будет выполняться два, так как 1 поток будет вы висеть, а получив кнопкой значение тру, продолжиться, также запуститься новый поток. как этого избежать?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.03.2021, 09:46
Ответы с готовыми решениями:

Thread.Sleep в главном потоке или как сделать нормальную задержку
Здравствуйте, мне нужно сделать задержку, хотелось бы через Thread.Sleep, но использование его в UI-потоке, как известно, приводит к...

Разница между Thread.Sleep и await Task.Delay
Здравствуйте! Плохо понимаю разницу между использованием: Thread.Sleep(1000); //Здесь код после задержки и ...

Аналог Thread.Sleep или Task.Delay
Есть ли какой-нибудь аналог функциям Thread.Sleep или Task.Delay ? Мне необходимо сделать задержку без блокирования главного потока....

13
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.03.2021, 11:56
У Task.Delay имеются перегрузки с CancellationToken
0
Эксперт .NET
 Аватар для Wolfdp
3789 / 1766 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
27.03.2021, 12:39
Цитата Сообщение от fry23 Посмотреть сообщение
как этого избежать?
для задачи делаете привязаный конкретно к ней поле, а не приватное для формы. И желательно использовать CancellationToken указаный выше, хотя при желании можно обойтись и bool.
0
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
27.03.2021, 15:26  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  private /*async*/ void button2_Click(object sender, EventArgs e)
        {
            _cancel = false;
            /*await */
            task = Task.Run(() => ProcessAsync());
 
        }
 
        private async Task ProcessAsync()
        {
            // del
           
            try
            {
                sqlDataAdapter = new SqlDataAdapter("SELECT *, 'Delete' AS [Delete] FROM Users", sqlConnection);
                sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
                dataSet = new DataSet();
 
                if (sqlConnection.State.ToString() != "Open") { sqlConnection = new SqlConnection(connectionString);
                    sqlConnection.Open(); }
 
                while (!_cancel)
                {
                    await Task.Delay(500);
                   // dataSet.Tables["Users"].Clear();
                    sqlDataAdapter.Fill(dataSet, "Users");
                    Invoke((MethodInvoker)delegate
                    {
                        label1.Text = sqlConnection.State.ToString() + DateTime.Now.ToLongTimeString();
                        dataGridView1.DataSource = dataSet.Tables["Users"];
                    });
                    //sqlConnection.Close();
                    int i = 0;
                    while (i<9 & !_cancel)
                    {
                        i++;
                        await Task.Delay(500);
                    }
                        
 
                }
      
            }
                catch (Exception ex)
            {
 
                MessageBox.Show(ex.Message);
            }
        }
 
        
 
       
 
        private void button3_Click(object sender, EventArgs e)
        {
            _cancel = true;
            label1.Text = "Стоп";
            sqlConnection.Close();
            MessageBox.Show(sqlConnection.State.ToString());
            //sleepingThread.Abort();
        }
 
        private void Form2_Load(object sender, EventArgs e)
        {
            sqlConnection = new SqlConnection(connectionString);
            sqlConnection.Open();
        }
я использую bool ну при перезапуске меньшем чем delay while уже выполняется два раза.

Добавлено через 11 минут
Someone007, посмотрите мой код пожалуйста, что то совсем не могу понять, где я свернул не туда
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.03.2021, 16:23
Зачем тут вообще все эти Task.Delay? Что вы хотите отменить: запрос к базе, или все эти задержки?
0
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
27.03.2021, 16:35  [ТС]
Отменить запрос к базе, но запрос стоит каждые 5 секунд, для получения важной информации. Мне нужна кнопка завершения запросов
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.03.2021, 16:49
В текущем виде сам запрос не отменить. И я даже не знаю поддерживает ли какой-то из методов, используемых вами для обращения к базе отмену, скорее всего нет...

Сам запрос долгий? Если нет, то можно и не заморачиваться с его отменой...

А чтобы нельзя было проблем с запуском нескольких потоков, можно просто блокировать кнопку пока не завершится отмена...

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        CancellationTokenSource cts;
 
        private async void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
 
            try
            {
                cts = new CancellationTokenSource();
                await Task.Delay(10000, cts.Token); // 10 sec
            }
            catch (TaskCanceledException tce)
            {
                MessageBox.Show("Task cancelled...");
            }
 
            cts.Dispose();
 
            button1.Enabled = true;
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            cts.Cancel();
        }
0
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
27.03.2021, 17:18  [ТС]
Запрос выполняется быстро, проблема в том что если в while я передаю true, и сразу нажимаю старт, начинают выполняться сразу два запроса. Так как в пока программа висела в delay, 5 секундном, запустился второй поток, а первый остался т.к. While не прервался. Получается надо прервать 5 секундный takj. Delay
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.03.2021, 17:49
Цитата Сообщение от fry23 Посмотреть сообщение
Получается надо прервать 5 секундный takj. Delay
Прерывайте, выше код как это сделать... И как кнопку заблокировать тоже чтобы не было случайных повторных запусков...
0
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
27.03.2021, 21:49  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp_sql
{
 
    // Проверить сохранения стоя на строке
    public partial class Form2 : Form
    {
        private SqlConnection sqlConnection = null;
        private SqlCommandBuilder sqlBuilder = null;
        private SqlDataAdapter sqlDataAdapter = null;
        public DataSet dataSet;
        string connectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\_\source\repos\WindowsFormsApp_sql\WindowsFormsApp_sql\Database1.mdf;Integrated Security=True";
        private bool _cancel = false;
        Task task;
        public Form2()
        {
            InitializeComponent();
            FormClosing += Form2_FormClosing;
        }
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            _cancel = true;
            sqlConnection.Close();
        }
 
        private /*async*/ void button2_Click(object sender, EventArgs e)
        {
            _cancel = false;
            task = Task.Run(() => ProcessAsync());
        }
        private async Task ProcessAsync()
        {
            try
            {
                sqlDataAdapter = new SqlDataAdapter("SELECT *, 'Delete' AS [Delete] FROM Users", sqlConnection);
                sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
                //dataSet = new DataSet();
                if (sqlConnection.State.ToString() != "Open")
                {
                    sqlConnection = new SqlConnection(connectionString);
                    sqlConnection.Open();
                }
 
                while (!_cancel)
                {
                    await Task.Delay(500);
                    dataSet = new DataSet();
                    sqlDataAdapter.Fill(dataSet, "Users");
                    Invoke((MethodInvoker)delegate
                    {
 
                        //dataGridView1.Refresh();
                        label1.Text = sqlConnection.State.ToString() + DateTime.Now.ToLongTimeString();
                        dataGridView1.DataSource = dataSet.Tables["Users"];
                    });
                    //sqlConnection.Close();
                    int i = 0;
 
                    //await Task.Delay(3000);
 
 
                    while (i < 9 & !_cancel)
                    {
                        i++;
                        await Task.Delay(500);
                    }
                }
 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
 
            _cancel = true;
 
            label1.Text = "Стоп";
            sqlConnection.Close();
            MessageBox.Show(sqlConnection.State.ToString());
            //sleepingThread.Abort();
        }
        private void Form2_Load(object sender, EventArgs e)
        {
            sqlConnection = new SqlConnection(connectionString);
            sqlConnection.Open();
        }
Я сделал это по старинке, вроде работает, думал найду тут более элегантный способ
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.03.2021, 22:26
Цитата Сообщение от fry23 Посмотреть сообщение
думал найду тут более элегантный способ
Вам предложили такой, но вы его проигнорировали.
0
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
28.03.2021, 00:27  [ТС]
Я не совсем разобрался, сейчас буду дальше тыкать, спасибо за терпение

Добавлено через 47 минут
А как прервать например task.delay(10000) ?
0
Эксперт .NET
 Аватар для Wolfdp
3789 / 1766 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
28.03.2021, 01:33
Лучший ответ Сообщение было отмечено fry23 как решение

Решение

Цитата Сообщение от fry23 Посмотреть сообщение
Я сделал это по старинке, вроде работает, думал найду тут более элегантный способ
Надеюсь я такой код на проекте никогда не увижу.

Сделайте хотя бы так... (ели шо, это не я писал. Точнее -- по хорошему все это безобразие нужно инкапсулировать в отдельный класс)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
        Task task;
        CancellationTokenSource cts;
 
 
        private void button2_Click(object sender, EventArgs e)
        {
            StopTask();
 
            cts = new CancellationTokenSource();
            task = Task.Run(() => ProcessAsync(cts.Token));
 
        }
 
        private void StopTask()
        {
            if (task != null)
            {
                cts.Cancel();
                task.Wait();
                cts.Dispose();
                task = null;
                cts = null;
            }
        }
 
 
        private async Task ProcessAsync(CancellationToken token)
        {
            // del
 
            try
            {
                using var sqlConnection = new SqlConnection(connectionString);
                using var sqlDataAdapter = new SqlDataAdapter("SELECT *, 'Delete' AS [Delete] FROM Users", sqlConnection);
                using var sqlBuilder = new SqlCommandBuilder(sqlDataAdapter);
                using var dataSet = new DataSet();
 
                sqlConnection.Open();
 
                while (!token.IsCancellationRequested)
                {
                    sqlDataAdapter.Fill(dataSet, "Users");
                    Invoke((MethodInvoker)delegate
                    {
                        label1.Text = sqlConnection.State.ToString() + DateTime.Now.ToLongTimeString();
                        dataGridView1.DataSource = dataSet.Tables["Users"];
                    });
                    await Task.Delay(new TimeSpan(0, 0, 5), token);
                }
 
            }
            catch (Exception ex)
            {
 
                MessageBox.Show(ex.Message);
            }
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            StopTask();
        }
 
        private void Form2_Load(object sender, EventArgs e)
        {
            //держать соединение постоянно смысла нет
            //sqlConnection = new SqlConnection(connectionString);
            //sqlConnection.Open();
        }
используйте using, он помогает не строчить Dispose и Close по каждому чиху.
1
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 28
28.03.2021, 15:25  [ТС]
Спасибо большое, буду пробовать

Добавлено через 5 часов 26 минут
Wolfdp, Работает как часы, теперь везде буду такой код писать. Спасибо огромное
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.03.2021, 15:25
Помогаю со студенческими работами здесь

Как работает await Task.Delay()
await Task.Delay(5000); Зачем используется асинхронность для задержки ?

Прервать ожидание Thread.Sleep
Можно ли прервать ожидание Thread.Sleep? У меня сейчас в отдельном потоке выполняется некий код, при нажатии кнопки стоп меняется...

Id текущего таска равен Null при использовании await Task.Delay(100);
Объясните, пожалуйста, почему используя await Task.Delay(100) в таске Task.CurrentId возвращает null? Async Task Run() { await...

Аналог Thread.Sleep в Task
Имеется пример который запускает пару потоков с задержкой. using System; using System.Collections.Generic; using System.Linq; using...

Дождаться выполнения Task без Thread.Sleep?
using System; public class Test { public static void Main() { Console.WriteLine(&quot;1&quot;); var task = new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru