Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.02.2017, 10:37   #11
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Тяжелее отменить/передвинуть
Так а ManualResetEvent для чего?
Отправляйте ему сигнал если надо отменить/передвинуть и запускайте с новым временем (проще всего просто всегда завершать поток и запускать снова если надо).
Если не было сигнала, то сам выйдет по таймауту (и он даже возвращает причину выхода, таймаут или сигнал).

Ну или если хотите костылей и велосипедов, то спите в цикле небольшими частями.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 02.02.2017, 11:17   #12
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
а зачем вы даты то отбрасываете? жизнь слишком простой показалась?
У меня максимально возможный отсчёт до запуска - 23:59:59. Зачем мне даты ? TimeSpan с этим отлично справляется, к тому же в Thread.Sleep можно указать TimeSpan ... Мне бессмысленно ещё и дату хранить отдельно для формочки с обратным отсчётом.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
DateTime отлично вычитается.
Я знаю, сути это не меняет.

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
проще всего просто всегда завершать поток
Проще Application.Restart().
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 02.02.2017, 11:24   #13
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Сейчас появился вопрос по поводу работы самого Thread.Sleep() ...
Допустим, у меня поток отправлен в сон на 10 часов; если я отправлю компьютер в режим сна (когда лампочка мигает) - то после возвращения компьютера из сна через пять часов поток будет спать 10, или 5 часов ?
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 02.02.2017, 11:50   #14
New man
Форумчанин
 
Регистрация: 24.01.2011
Сообщений: 774
По умолчанию

Спать пять часов для потока как-то неправильно.

А вообще, почему-то вспомнил баян.
Код:
void get_tomorrow_date( struct timeval *date )
  {
     sleep( 86400 ); // 60 * 60 * 24
     gettimeofday( date, 0 );
  }
a.k.a. Angelicos Phosphoros
Мой сайт
New man вне форума Ответить с цитированием
Старый 02.02.2017, 11:54   #15
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от New man Посмотреть сообщение
Спать пять часов для потока как-то неправильно
Не могу не согласиться ... Поэтому переделал свой кодЪ
Код:
// в самом начале потока
if (checkDelay.Checked) // пользователь поставил галочку; для чтения Invoke нужен ?
{
	while (true)
	{
		try
		{
			if (delay_form.end_delay) // формочка, которая отображает оставшееся время, и её внешний флаг
				break;
			else {}
		}
		catch
		{
			break; // а вдруг асинхрон ?
		}
		Thread.Sleep(1000); // так при возврате компьютера из сна можно адекватно продолжить работу
	}
	this.Invoke(new Action(() => { this.Visible=this.ShowInTaskbar=true; })); // главная форма скрывается до старта этого потока
} else {}
Цитата:
Сообщение от New man Посмотреть сообщение
вспомнил баян
А баян в тему ...
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 02.02.2017 в 11:58.
OmegaBerkut вне форума Ответить с цитированием
Старый 02.02.2017, 12:52   #16
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
У меня максимально возможный отсчёт до запуска - 23:59:59. Зачем мне даты ? TimeSpan с этим отлично справляется, к тому же в Thread.Sleep можно указать TimeSpan ... Мне бессмысленно ещё и дату хранить отдельно для формочки с обратным отсчётом.
TimeSpan это результат разности дат, он отлично справится и с годом.

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Я знаю, сути это не меняет.
ну костыли это ваше право.

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Проще Application.Restart().
проще закрыть VS и удалить.

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Сейчас появился вопрос по поводу работы самого Thread.Sleep() ...
Допустим, у меня поток отправлен в сон на 10 часов; если я отправлю компьютер в режим сна (когда лампочка мигает) - то после возвращения компьютера из сна через пять часов поток будет спать 10, или 5 часов ?
нет стандарта на этот счет, ибо она не создана для такого времени, может и не учестся время вообще.
для учета со сном и вывода из него есть WaitableTimer.

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Поэтому переделал свой кодЪ
у вас время события есть, чего чекать вечно? вы бы еще вообще выкинули Sleep, чтоб уж точно не упустить.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.02.2017, 13:34   #17
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
вы бы еще вообще выкинули Sleep, чтоб уж точно не упустить
Ежесекундная проверка никому не навредит. Как поток, так и процесс с самым низким приоритетом.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
проще закрыть VS и удалить
Так может и жить проще, но так не интересно.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ну костыли это ваше право
По сути, тогда весь мой код является набором костылей. И я не возражаю, ибо программирую более-менее полноценно всего два года, а это ещё не стаж.

А так, явным костылём можно назвать функцию, которая дополнительно считает, сколько прошло времени с момента запуска обратного отсчёта:
Код:
private bool OverTime()
{
	goneticks+=DateTime.Now.Ticks-c_ticks;
	c_ticks=DateTime.Now.Ticks;
	return (goneticks>=requestticks);
}
Нужна для того, что бы таймер понял, что процесс висел без работы (компьютер был во сне), и длилось это дольше чем нужно программе/пользователю. Иначе - после выхода из сна отсчёт продолжится/начнётся "по новой", как для следующего дня ...
Код:
private void timerDelay_Tick(object sender,EventArgs e)
{
	TimeSpan c_start=inner_start; // дабы не покалечить базовые данные (readonly)
	if (TimeSpan.Compare(c_start,DateTime.Now.TimeOfDay)<0)
		c_start=c_start.Add(new TimeSpan(1,0,0,0,0));
	else {}
	c_start=c_start.Subtract(DateTime.Now.TimeOfDay);
	leftseconds=c_start.TotalSeconds;
	string info="Отложенный запуск: обратный отсчёт\r\n"+c_start.ToString();
	if (info.IndexOf('.')>-1)
		info=info.Remove(info.IndexOf('.')); // убрать миллисекунды, для красоты
	else {}
	labelDelay.Text=info;
	info=null;
	if (c_start.TotalSeconds<(double)2 || OverTime())
	{
		timerDelay.Enabled=false;
		end_delay=true;
		this.Close();
	} else {}
}
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 02.02.2017, 14:02   #18
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
Ежесекундная проверка никому не навредит.
Речь не о том была.
Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
// формочка, которая отображает оставшееся время, и её внешний флаг
Это как?
Цитата:
Сообщение от OmegaBerkut Посмотреть сообщение
для чтения Invoke нужен ?
Да, но вообще лучше не писать так, а отделять UI от всего остального.

Например как-нибудь так. Просто функция, которая принимает время и callback (ссылка на функцию, которая вызовется в конце). И возвращает объект, на котором можно вызвать Cancel() для досрочного завершения.

Код:
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication6
{
    public partial class Form1 : Form
    {
        private SchedulerTask _currentTask;

        private bool _isRunning;
        private bool IsRunning
        {
            get { return _isRunning; }
            set
            {
                _isRunning = value;
                UpdateFormState();
            }
        }

        public Form1()
        {
            InitializeComponent();

            IsRunning = false;

            var timer = new Timer()
            {
                Interval = 250
            };
            timer.Tick += (sender, args) =>
            {
                if (IsRunning)
                {
                    lblTimeLeft.Text = "Осталось: " + (DateTime.Now - _currentTask.EndTime).ToString("mm\\:ss");
                }
            };
            timer.Start();
        }

        private void UpdateFormState()
        {
            btnStart.Text = IsRunning ? "Stop" : "Start";
            lblTimeLeft.Visible = IsRunning;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (IsRunning)
            {
                _currentTask.Cancel();
            }
            else
            {
                _currentTask = new Scheduler().Wait(TimeSpan.FromSeconds(5), () =>
                {
                    Invoke(new Action(() =>
                    {
                        MessageBox.Show("Hello");
                        IsRunning = false;
                    }));
                });
            }

            IsRunning = !IsRunning;
        }
    }
}
Код:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace WindowsFormsApplication6
{
    public class SchedulerTask
    {
        private readonly CancellationTokenSource _cancellationTokenSource;

        public SchedulerTask(CancellationTokenSource cancellationTokenSource, DateTime endTime)
        {
            _cancellationTokenSource = cancellationTokenSource;
            EndTime = endTime;
        }

        public DateTime EndTime { get; }

        public void Cancel()
        {
            _cancellationTokenSource.Cancel();
        }
    }

    class Scheduler
    {
        public SchedulerTask Wait(TimeSpan delay, Action callback)
        {
            var endTime = DateTime.Now.Add(delay);

            var cts = new CancellationTokenSource();
            var cancellationToken = cts.Token;

            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    if (DateTime.Now > endTime)
                    {
                        callback();
                        break;
                    }

                    if (cancellationToken.IsCancellationRequested) // или cancellationToken.ThrowIfCancellationRequested();
                    {
                        return;
                    }

                    Thread.Sleep(1000);
                }
            }, cancellationToken)
                .ContinueWith(task =>
                {
                    if (task.IsFaulted)
                    {
                        Debug.WriteLine(task.Exception);
                    }
                });

            return new SchedulerTask(cts, endTime);
        }
    }
}
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 05.02.2017 в 17:14.
Alex11223 вне форума Ответить с цитированием
Старый 02.02.2017, 14:13   #19
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

А ну да ...
Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
TimeSpan это результат разности дат, он отлично справится и с годом.
Это я знаю ... Собственно, это и есть ответ на ваш вопрос, зачем я отбрасываю даты - что бы при сравнении/разности не получать артефакты.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 02.02.2017, 14:20   #20
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Это как?
Отдельно соорудил форму с лейбой, на которую (лейбу) таймер этой самой формы раз в секунду скидывает информацию о том, сколько времени осталось. Внешний флаг - public bool end_delay - выглядит приятнее, чем делать таймер public, и смотреть, когда он включён.
Цитата:
Сообщение от Alex11223 Посмотреть сообщение
но вообще лучше не писать так, а отделять UI от всего остального.
Собсна, так и сделал.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Аналог Thread.Sleep или Task.Delay vovaza29 C# (си шарп) 12 17.09.2015 21:22
работа с файлом txt с помощью потока thread в С++ helpmybrains Помощь студентам 0 04.12.2014 10:49
Истекло время ожидания (Timeout). Время ожидания истекло до завершения операции или сервер не отвечает. kgs_forum C# (си шарп) 1 20.08.2013 20:14
Thread и Queue: пересылка данных из потока в поток fshlik C# (си шарп) 5 16.02.2013 13:27
Контролируемый Sleep потока. Человек_Борща Win Api 10 26.09.2012 12:14