Вход/Регистрация
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
вернуться

Троелсен Эндрю

Шрифт:

sealed class BinaryOp: System.MulticastDelegate {

 public BinaryOp(object target, uint functionAddress);

 public void Invoke(int x, int y);

 public IAsyncResult BeginInvoke(int x, int y, AsyncCallback cb, object state);

 public int EndInvoke(IAsyncResult result);

}

Напомним, что генерируемый метод Invoke используется для вызова методов, обслуживаемых объектом делегата в синхронном режиме. В этом случае вызывающий поток (например, первичный поток приложения) вынужден ждать, пока не завершится вызов делегата. Также напомним, что в C# метод Invoke не вызывается в программном коде явно, а запускается в фоновом режиме при использовании "нормального синтаксиса" вызова метода. Рассмотрите следующий программный код, в котором статический метод Add вызывается в синхронной (т.е. блокирующей) форме.

// Это требуется для вызова Thread.Sleep.

using System.Threading;

using System;

namespace SyncDelegate {

 public delegate int BinaryOp(int x, int y);

 class Program {

static void Main(string[] args) {

Console.WriteLine("***** Синхронный вызов, делегата *****");

// Вывод ID выполняемого потока.

Console.WriteLine("Вызван Main в потоке {0}.", Thread.CurrentThread.GetHashCode);

// Вызов Add в синхронной форме.

BinaryOp b = new BinaryOp(Add);

int answer = b(10, 10);

// Эти строки не будут выполнены до завершения

// работы метода Add.

Console.WriteLine("В Main еще есть работа!");

Console.WriteLine("10 + 10 равно {0}.", answer);

Console.ReadLine;

}

static int Add(int x, int y) {

// Вывод ID выполняемого потока.

Console.WriteLine("Вызван Add в потоке {0}.", Thread.CurrentThread.GetHashCode);

// Пауза примерно 5 секунд для

// имитации длительной операции.

Thread.Sleep(5000);

return x + у;

}

 }

}

Сначала заметим, что в этой программе используется пространство имен System.Threading. В методе Add вызывается статический метод Thread.Sleep, чтобы приостановить вызывающий поток (приблизительно) на пять секунд для имитации задачи, выполнение которой требует много времени. Поскольку метод Add вызывается в синхронной форме, метод Main не напечатает результат операции до тех пор, пока не завершится работа метода Add.

Далее заметим, что метод Main получает доступ к текущему потоку (с помощью Thread.CurrentThread) и печатает его хешированный код. Поскольку этот хешированный код представляет объект в конкретном состоянии, соответствующее значение можно использовать как "грубый" идентификатор потока. Та же логика используется в статическом методе Add. Как и следует ожидать, поскольку вся работа в этом приложении выполняется исключительно первичным потоком, вы увидите одинаковые хешированные значения в консольном выводе программы (рис. 14.1).

Рис. 14.1. Синхронные вызовы методов "блокируют" другие вызовы

При выполнении этой программы вы заметите, что перед тем выполнением Console.WriteLine произойдет пятисекундная задержка. И хотя многие методы (если не подавляющее их большинство) могут вызваться синхронно совершенно безболезненно, делегатам .NET, если это необходимо, можно дать указание вызывать методы асинхронно.

Исходный код. Проект SyncDelegate размещен в подкаталоге, соответствующем главе 14.

  • Читать дальше
  • 1
  • ...
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: