Шрифт:
Напомним, что генерируемый метод Invoke используется для вызова методов, обслуживаемых объектом делегата в синхронном режиме. В этом случае вызывающий поток (например, первичный поток приложения) вынужден ждать, пока не завершится вызов делегата. Также напомним, что в C# метод Invoke не вызывается в программном коде явно, а запускается в фоновом режиме при использовании "нормального синтаксиса" вызова метода. Рассмотрите следующий программный код, в котором статический метод Add вызывается в синхронной (т.е. блокирующей) форме.
Сначала заметим, что в этой программе используется пространство имен System.Threading. В методе Add вызывается статический метод Thread.Sleep, чтобы приостановить вызывающий поток (приблизительно) на пять секунд для имитации задачи, выполнение которой требует много времени. Поскольку метод Add вызывается в синхронной форме, метод Main не напечатает результат операции до тех пор, пока не завершится работа метода Add.
Далее заметим, что метод Main получает доступ к текущему потоку (с помощью Thread.CurrentThread) и печатает его хешированный код. Поскольку этот хешированный код представляет объект в конкретном состоянии, соответствующее значение можно использовать как "грубый" идентификатор потока. Та же логика используется в статическом методе Add. Как и следует ожидать, поскольку вся работа в этом приложении выполняется исключительно первичным потоком, вы увидите одинаковые хешированные значения в консольном выводе программы (рис. 14.1).
Рис. 14.1. Синхронные вызовы методов "блокируют" другие вызовы
При выполнении этой программы вы заметите, что перед тем выполнением Console.WriteLine произойдет пятисекундная задержка. И хотя многие методы (если не подавляющее их большинство) могут вызваться синхронно совершенно безболезненно, делегатам .NET, если это необходимо, можно дать указание вызывать методы асинхронно.
Исходный код. Проект SyncDelegate размещен в подкаталоге, соответствующем главе 14.