powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Какую бы конструкцию тут можно придумать ?
15 сообщений из 15, страница 1 из 1
Какую бы конструкцию тут можно придумать ?
    #38871744
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет.

Появился вопросик, из разряда философии.
На примере одно сервиса: отдельно от основной деятельности сервиса, имеется задачка периодически делать дополнительную работу - проверять shared папку на файлы и их обрабатывать.

Так вот. Я думаю - как эффективней это бы реализовать ?

1. Мне в принципе не нравится идея запустить отдельный поток, который будет бездельничать, но периодически просыпаться и работать - постоянно занимая поток для себя (ну по типу Thread.Sleep - когда поток бесполезно висит)

2. Я хочу улучшить предыдущий вариант. Если прикрутить async может получится ! Вместо того, чтобы впадать в просто sleep до следующей итерации - можно впадать в task.delay с помощью await.

3. Основной рабочий поток, периодически сам создает task (через некоторое количество итераций; или проверяя по отрезку времени - что пора запустить поток для задачки; или вообще при каждой итерации вызывать метод вспомогательного класса, а он уже смотрит и решает - пора ли ему работать, и если нужно запустить отдельный поток)

В целом мне нравится идея со вторым вариантом. И мне кажется это будет очень эффективно.
Примерный код:

Код: 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.
        static void Main(string[] args)
        {
           UtilityClass uc = new UtilityClass(CancelationToken...);
           Task tsk = uc.StartWork()
           cts.cancel();
           await tsk;
           .... подчистка tsk (ну проверить, что там нет исключения вообще и т.д.)
        }

public class UtilityClass
{
  private CancelationToken _token;

  public UtilityClass (CancelationToken token)
  {
     if (token==null)
       throw new ArgumentNullException ("token");
     _token = token;
  }

  public async Task StartWork ()
  {
     // можно без action сразу лямбду в Task.Run пульнуть. не суть.
     Action act = ()=> {
        while (!token.IsCancellationRequested)
        {
          .... полезная нагрузка...
          await Task.Delay (time, _token)    << Вот тут сама задумка.
        }      
     };
    return Task.Run (act,...)     
  }
}



В принципе это можно вынести в отдельный класс - которому будет передаваться Action для выполнения периодической задачи.

Что думаете ? Главный вопрос - не будет ли тут простоя потока ? Больше всего я не хочу, чтобы была такая картина:
работа 100мс....sleeeeeeeep 3 минуты (держим поток).....работа 100 мс....sleeeep(с удержанием потока 3 минуты).....

Насколько я понимаю, применение await как раз позволит потоку освободится в пул и все будет максимально эффективно (как бы это еще подтвердить - графиками или другими средствами).
Хочется, чтобы задача выполнялась по таймауту - а в свободное время отдавала поток в пул и не отбирала ресурсы.
Будет работать задумка ? Будет ли она эффективна ? Или есть решения получше ?
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38871758
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот код. В студии работает отлично. Нужно лишь понять эффективен ли он ? Не простаивает ли поток ?

Код: 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.
class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            UtilityClass uc = new UtilityClass(cts.Token);
            var task =  uc.StartWork ();

            Console.ReadLine();
            cts.Cancel();

            task.Wait();

            Console.WriteLine("Done");

        }
    }

    public class UtilityClass
    {
        private CancellationToken _token;

        public UtilityClass(CancellationToken token)
        {
            if (token == null)
                throw new ArgumentNullException("token");
            _token = token;
        }

        public async Task StartWork()
        {
            await Task.Run(async () =>            
            {
                try
                {

                    while (!_token.IsCancellationRequested)
                    {
                        await Task.Delay(1000, _token);
                        Console.WriteLine("Ping: " + DateTime.Now.ToString());
                    }
                }
                catch (TaskCanceledException) { }
            });
        }            
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38871768
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ProBiotek,

Код: c#
1.
Console.WriteLine("Ping: " + Thread.CurrentThread.ManagedThreadId);


Номер потока меняется.

Имхо, если нужно работу выполнять периодически, то проще использовать таймер.
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38871959
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если нет явных сигналов и возможности использовать WaitHandle, по мне вполне вариант. Единственное, я не рекомендую ставить async/await без надобности, если всего один Task, то его можно вернуть напрямую. Да и лишнее отслеживание наличия контекста синхронизации, думаю ни к чему, рекомендую ставить ConfigureAwait(false).

Скажем, так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public Task StartWork()
        {
            return Task.Run(async () =>            
            {
                try
                {

                    while (!_token.IsCancellationRequested)
                    {
                        await Task.Delay(1000, _token).ConfigureAwait(false);
                        Console.WriteLine("Ping: " + DateTime.Now.ToString());
                    }
                }
                catch (TaskCanceledException) { }
            });
        }  
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38871971
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ProBiotekПривет.
делать дополнительную работу - проверять shared папку на файлы и их обрабатывать.


Timer самый то, что нужно. Зачем все усложнять?
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38871981
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычный windows сервис + Quartz.net
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872106
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Обычный windows сервис + Quartz.net
Не вариант... Убивает элемент "творчества" в работе превращая её в рутину...
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872131
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvikProBiotek,

Код: c#
1.
Console.WriteLine("Ping: " + Thread.CurrentThread.ManagedThreadId);


Номер потока меняется.

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

а да... чот я про таймеры не подумал :) Решил сделать велосипед.



КОНЕЧНО же меняются потоки :)
async/await берет поток из пула и возвращает его при ожидании. В этом его вся суть. В отличае от какого нибудь Sleep, который держит поток пока слипает. async/Await возвращает поток в пул - где его может взять другой async/await.
В итоге один поток может обслужить под сотню параллельных обработчиков - если они делают очень мелкую работу (10-50 мс), а остальное время слипают через Task.Delay. И если заменить Task.Delay на Thread.Sleep, производительность мгновенно упадет с 100-300 одновременно работающих потоков, до 4-8 (сколько ядер в системе) !
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872140
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS. А какого черта Concurrency Visualizer не входит в VS 2013 по умолчанию ? Я в шоке, что приходится его ставить отдельно. Забыл вот - и пол часа тыкал в менюшках, искал его. Нужно разобратся теперь как его использовать и анализировать его показания.
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872148
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ilya81 рекомендую ставить ConfigureAwait(false).
Точно. Конечно же ) Спасибо.

В исходниках C#6 код, который работает с asunc/await он весь там напичкан ConfigureAwait под завязку.
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872242
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Обычный windows сервис + Quartz.net

Quartz.net - в первый раз о нем услышал... Очень заинтересовало, спасибо.
Хорошая штука ? Много где нашли применений ?

Собственно, в чем разница Quartz.net от обычного таймера, к примеру ?
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872289
Фотография Нахлобуч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872316
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ProBiotekArm79Обычный windows сервис + Quartz.net

Quartz.net - в первый раз о нем услышал... Очень заинтересовало, спасибо.
Хорошая штука ? Много где нашли применений ?

Собственно, в чем разница Quartz.net от обычного таймера, к примеру ?

Если рассматривать в контексте движения, какая разница между колесом и автомобилем? Если колесо, то чтобы оно ехало куда надо и как надо, нужно поверх него много что накрутить. А автомобиль - он может ехать на гораздо большие расстояния, но ему нужен бензин, водитель, + куча попутных действий. Зато и поездка комфортнее.

В общем, кварц.нет на хостинге службы для организации каких либо работ по расписанию или через заданные интервалы времени - это самое то. Особенно если учесть, что он понимает формат cron
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872501
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нахлобуч ThreadPool.RegisterWaitForSingleObject

А чем этот метод лучше обычного таймера ? Обычный таймер, вроде, тоже для своего выполнения использует поток из пула.
...
Рейтинг: 0 / 0
Какую бы конструкцию тут можно придумать ?
    #38872867
Poke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЕвгенийВTimer самый то, что нужно. Зачем все усложнять?

Я скажу ещё проще: FileSystemWatcher
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Какую бы конструкцию тут можно придумать ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]