Составители:
Рубрика:
gd, 1000, false
);
Thread.Sleep( 2500 );
ev.Set();
Console.ReadLine();
}
}
}
Приведенный пример демонстрирует использование периодического
вызова асинхронной процедуры – при регистрации делегата
(RegisterWaitForSingleObject) указывается максимальное время ожидания
1 секунда (1000 миллисекунд), после чего основной поток переводится в
состояние «спячки» на 2.5 секунды. За это время в очередь пула поступает
два вызова асинхронных процедур (с признаком вызова по тайм-ауту). Че-
рез 2.5 секунды основной поток пробуждается, переводит событие в сво-
бодное состояние, и в очередь пула поступает третий вызов. При обработ-
ке этого вызова регистрация делегата отменяется.
Последний способ связан с использованием методов BeginInvoke и
EndInvoke делегатов. Когда определяется какой-либо делегат функции, для
него будут определены методы: BeginInvoke (содержащий все аргументы
делегата плюс два дополнительных – AsyncCallback, который может быть
вызван по завершении обработки асинхронного вызова, и AsyncState, с
помощью которого можно определить состояние асинхронной процеду-
ры) и EndInvoke, содержащий все выходные параметры (т.е. описанные как
inout или out), плюс IAsyncResult, позволяющий узнать результат выпол-
нения процедуры.
Таким образом, использование BeginInvoke позволяет не только по-
ставить в очередь вызов асинхронной процедуры, но также связать с за-
вершением ее обработки еще один асинхронный вызов. Метод EndInvoke
служит для ожидания завершения обработки асинхронной процедуры:
using System;
using System.Threading;
namespace TestNamespace {
public class GreetingData {
private string m_greeting;
public GreetingData( string text ) { m_greeting = text; }
public static void Invoke( GreetingData arg ) {
Console.WriteLine( arg.m_greeting );
}
}
Разработка параллельных приложений для ОС Windows
259
При постановке в очередь асинхронного вызова можно указать объ-
ект, который является аргументом асинхронной процедуры (при создании
собственных потоков передача аргументов процедуре потока затрудни-
тельна).
Второй способ вызова асинхронных процедур связан с использованием
объектов, производных от класса System.Threading.WaitHandle (это события
и мьютексы). При этом вызов асинхронной процедуры связывается с пере-
водом объекта в свободное состояние. Данный метод может быть использо-
ван также для организации повторяющегося через определенные интервалы
вызова асинхронных процедур – при регистрации делегата указывается ма-
ксимальный интервал ожидания, и если он исчерпывается, то вызов разме-
щается в очереди пула, даже если объект остался занятым. Если объект по-
прежнему остается занятым, то вызов процедуры будет периодически разме-
щаться в очереди после исчерпания каждого интервала ожидания.
using System;
using System.Threading;
namespace TestNamespace {
class GreetingData {
private string m_greeting;
private RegisteredWaitHandle m_waithandle;
public GreetingData( string text ) { m_greeting = text; }
public void Invoke() { Console.WriteLine( m_greeting ); }
public RegisteredWaitHandle WaitHandle {
set {
if (value==null) m_waithandle.Unregister( null );
m_waithandle = value;
}
}
}
class TestApp {
static void AsyncProc( Object arg, bool isTimeout ) {
GreetingData gd = (GreetingData)arg;
if ( !isTimeout ) gd.WaitHandle = null;
gd.Invoke();
}
public static void Main() {
GreetingData gd = new GreetingData(“Hello”);
AutoResetEvent ev = new AutoResetEvent(false);
gd.WaitHandle=ThreadPool.RegisterWaitForSingleObject(
ev, new WaitOrTimerCallback(AsyncProc),
258
CIL и системное программирование в Microsoft .NET
258 CIL и системное программирование в Microsoft .NET Разработка параллельных приложений для ОС Windows 259 При постановке в очередь асинхронного вызова можно указать объ- gd, 1000, false ект, который является аргументом асинхронной процедуры (при создании ); собственных потоков передача аргументов процедуре потока затрудни- Thread.Sleep( 2500 ); тельна). ev.Set(); Второй способ вызова асинхронных процедур связан с использованием Console.ReadLine(); объектов, производных от класса System.Threading.WaitHandle (это события } и мьютексы). При этом вызов асинхронной процедуры связывается с пере- } водом объекта в свободное состояние. Данный метод может быть использо- } ван также для организации повторяющегося через определенные интервалы Приведенный пример демонстрирует использование периодического вызова асинхронных процедур – при регистрации делегата указывается ма- вызова асинхронной процедуры – при регистрации делегата ксимальный интервал ожидания, и если он исчерпывается, то вызов разме- (RegisterWaitForSingleObject) указывается максимальное время ожидания щается в очереди пула, даже если объект остался занятым. Если объект по- 1 секунда (1000 миллисекунд), после чего основной поток переводится в прежнему остается занятым, то вызов процедуры будет периодически разме- состояние «спячки» на 2.5 секунды. За это время в очередь пула поступает щаться в очереди после исчерпания каждого интервала ожидания. два вызова асинхронных процедур (с признаком вызова по тайм-ауту). Че- рез 2.5 секунды основной поток пробуждается, переводит событие в сво- using System; бодное состояние, и в очередь пула поступает третий вызов. При обработ- using System.Threading; ке этого вызова регистрация делегата отменяется. Последний способ связан с использованием методов BeginInvoke и namespace TestNamespace { EndInvoke делегатов. Когда определяется какой-либо делегат функции, для class GreetingData { него будут определены методы: BeginInvoke (содержащий все аргументы private string m_greeting; делегата плюс два дополнительных – AsyncCallback, который может быть private RegisteredWaitHandle m_waithandle; вызван по завершении обработки асинхронного вызова, и AsyncState, с public GreetingData( string text ) { m_greeting = text; } помощью которого можно определить состояние асинхронной процеду- public void Invoke() { Console.WriteLine( m_greeting ); } ры) и EndInvoke, содержащий все выходные параметры (т.е. описанные как public RegisteredWaitHandle WaitHandle { inout или out), плюс IAsyncResult, позволяющий узнать результат выпол- set { нения процедуры. if (value==null) m_waithandle.Unregister( null ); Таким образом, использование BeginInvoke позволяет не только по- m_waithandle = value; ставить в очередь вызов асинхронной процедуры, но также связать с за- } вершением ее обработки еще один асинхронный вызов. Метод EndInvoke } служит для ожидания завершения обработки асинхронной процедуры: } class TestApp { using System; static void AsyncProc( Object arg, bool isTimeout ) { using System.Threading; GreetingData gd = (GreetingData)arg; if ( !isTimeout ) gd.WaitHandle = null; namespace TestNamespace { gd.Invoke(); public class GreetingData { } private string m_greeting; public static void Main() { public GreetingData( string text ) { m_greeting = text; } GreetingData gd = new GreetingData(“Hello”); public static void Invoke( GreetingData arg ) { AutoResetEvent ev = new AutoResetEvent(false); Console.WriteLine( arg.m_greeting ); gd.WaitHandle=ThreadPool.RegisterWaitForSingleObject( } ev, new WaitOrTimerCallback(AsyncProc), }
Страницы
- « первая
- ‹ предыдущая
- …
- 134
- 135
- 136
- 137
- 138
- …
- следующая ›
- последняя »