Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 283 284 285 286 287 288 289 290 291 ... 642

Console.WriteLine("***** Working with Timer type *****n");

Console.ReadLine();

static void PrintTime(object state)

{

  Console.WriteLine("Time is: {0}",

    DateTime.Now.ToLongTimeString());

}

Обратите внимание, что метод PrintTime() принимает единственный параметр типа System.Object и возвращает void. Это обязательно, потому что делегат TimerCallback может вызывать только методы, которые соответствуют такой сигнатуре. Значение, передаваемое целевому методу делегата TimerCallback, может быть объектом любого типа (в случае примера с электронной почтой параметр может представлять имя сервера Microsoft Exchange Server для взаимодействия в течение процесса). Также обратите внимание, что поскольку параметр на самом деле является экземпляром типа System.Object, в нем можно передавать несколько аргументов, используя System.Array или специальный класс либо структуру.

Следующий шаг связан с конфигурированием экземпляра делегата TimerCallback и передачей его объекту Timer. В дополнение к настройке делегата TimerCallback конструктор Timer позволяет указывать необязательный информационный параметр для передачи целевому методу делегата (определенный как System.Object), интервал вызова метода и период ожидания (в миллисекундах), который должен истечь перед первым вызовом. Вот пример:

Console.WriteLine("***** Working with Timer type *****n");

// Создать делегат для типа Timer.

TimerCallback timeCB = new TimerCallback(PrintTime);

// Установить параметры таймера.

Timer t = new Timer(

  timeCB,     // Объект делегата TimerCallback.

  null,       // Информация для передачи в вызванный метод.

              // (null, если информация отсутствует).

  0,          // Период ожидания перед запуском (в миллисекундах).

  1000);      // Интервал между вызовами (в миллисекундах).

Console.WriteLine("Hit Enter key to terminate...");

Console.ReadLine();

В этом случае метод PrintTime() вызывается приблизительно каждую секунду и не получает никакой дополнительной информации. Ниже показан вывод примера:

***** Working with Timer type *****

Hit key to terminate...

Time is: 6:51:48 PM

Time is: 6:51:49 PM

Time is: 6:51:50 PM

Time is: 6:51:51 PM

Time is: 6:51:52 PM

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

Press any key to continue ...

Чтобы передать целевому методу делегата какую-то информацию, необходимо просто заменить значение null во втором параметре конструктора подходящей информацией, например:

// Установить параметры таймера.

Timer t = new Timer(timeCB, "Hello From C# 9.0", 0, 1000);

You can then obtain the incoming data as follows:static void PrintTime(object state)

{

  Console.WriteLine("Time is: {0}, Param is: {1}",

    DateTime.Now.ToLongTimeString(), state.ToString());

}

Использование автономного отбрасывания (нововведение в версии 7.0)

В предыдущем примере переменная Timer не применяется в каком-либо пути выполнения и потому может быть заменена отбрасыванием:

 var _ = new Timer(

    timeCB,  // Объект делегата TimerCallback.

    null,    // Информация для передачи в вызванный метод

             // (null, если информация отсутствует).

    0,       // Период ожидания перед запуском

             // (в миллисекундах).

    1000);   // Интервал между вызовами

             // (в миллисекундах). 

Класс ThreadPool

Следующей темой о потоках, которую мы рассмотрим в настоящей главе, будет роль пула потоков. Запуск нового потока связан с затратами, поэтому в целях повышения эффективности пул потоков удерживает созданные (но неактивные) потоки до тех пор, пока они не понадобятся. Для взаимодействия с этим пулом ожидающих потоков в пространстве имен System.Threading предлагается класс ThreadPool.

Чтобы запросить поток из пула для обработки вызова метода, можно использовать метод ThreadPool.QueueUserWorkItem(). Он имеет перегруженную версию, которая позволяет в дополнение к экземпляру делегата WaitCallback указывать необязательный параметр System.Object для передачи специальных данных состояния:

public static class ThreadPool

{

  ...

  public static bool QueueUserWorkItem(WaitCallback callBack);

  public static bool QueueUserWorkItem(WaitCallback callBack,

                                      object state);

}

Делегат WaitCallback может указывать на любой метод, который принимает в качестве единственного параметра экземпляр System.Object (представляющий необязательные данные состояния) и ничего не возвращает. Обратите внимание, что если при вызове QueueUserWorkItem() не задается экземпляр System.Object, то среда .NET Core Runtime автоматически передает значение null. Чтобы продемонстрировать работу методов очередей, работающих с пулом потоков .NET Core Runtime, рассмотрим еще раз программу (в проекте консольного приложения по имени ThreadPoolApp), в которой применяется тип Printer. На этот раз массив объектов Thread не создается вручную, а метод PrintNumbers() будет назначаться членам пула потоков:

1 ... 283 284 285 286 287 288 289 290 291 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий