|
Página 4 de 5
El siguiente método nos muestra como se procesan los elementos en el puerto. En el siguiente ejemplo, primero se crea un objeto Port y posteriormente se llama al método Arbiter.MultiItemReceiver() que se encargará de procesas múltiples elementos. Este método es muy similar al método Receiver excepto que hay que indicar el número de elementos que se deben añadir al puerto antes de procesar cualquiera de ellos. En nuestro caso, indicamos que deben añadirse 10 elementos, posteriormente los añadirá uno a uno. Finalmente se añaden de 0 hasta 50 elementos, es decir, el procesamiento de las cadenas se ejecutará 5 veces.
private static void MultipleItemDemo(DispatcherQueue dq) { Port<String> stringPort = new Port<String>(); Arbiter.Activate(dq, Arbiter.MultipleItemReceive(true, stringPort, 10, delegate(String[] strings) { Msg("Ten strings={0}", String.Join(", ", strings)); }) );
for (int i = 0; i < 50; i++) stringPort.Post(i.ToString());
HitEnter();
}
Si ejecutamos el código anterior, obtendríamos el siguiente resultado:
ThreadID=12: Ten strings=0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ThreadID=12: Ten strings=10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ThreadID=12: Ten strings=20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ThreadID=12: Ten strings=30, 31, 32, 33, 34, 35, 36, 37, 38, 39 ThreadID=12: Ten strings=40, 41, 42, 43, 44, 45, 46, 47, 48, 49 Hit <Enter> to continue demo
Para ver como se leen los datos de un archivo asíncronamente, podemos analizar el siguiente ejemplo:
private static void AsyncStreamDemo(DispatcherQueue dq) { FileStream fs = new FileStream(@"C:\Boot.ini", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 8 * 1024, FileOptions.Asynchronous); Byte[] data = new Byte[10000]; Port<Int32> bytesReadPort = null; Port<Exception> failurePort = null; ApmToCcrAdapters.Read(fs, data, 0, data.Length, ref bytesReadPort, ref failurePort);
Arbiter.Activate(dq, Arbiter.Choice( Arbiter.Receive(false, bytesReadPort, delegate(Int32 bytesRead) { Array.Resize(ref data, bytesRead); Msg("Read completed, bytes read={0}, data follows:{1}{2}", data.Length, Environment.NewLine, Encoding.ASCII.GetString(data)); }),
Arbiter.Receive(false, failurePort, delegate(Exception e) { Msg("Read failed, error={0}", e.Message); }) ) );
HitEnter(); }
Primero creamos un objeto FileStream, con el que vamos a intentar leer el archivo que le pasamos cuando lo construimos. Además, se añaden diferentes opciones de las que dispone FileStream. Básicamente, cuando inicializamos una operación asíncrona con el método Stream pueden ocurrir dos cosas: que la operación de entrada-salida se complete y devuelva el número de bits leídos, o que la operación falle, indicándolo con una excepción. Así que, en nuestro ejemplo, creamos un objeto Port<Exception> y otro Port<Int32>, ambos inicializados a null. Posteriormente llamamos al método Read, pasándole sus correspondientes argumentos y dos objetos Port. Luego comenzará la operación asíncrona de lectura. Si la operación se ha realizado correctamente, el número de bits se añadirá al puerto Port<Int32>, sino se llamará a EndRead y se lanzará una excepción.
Para coordinar los posibles resultados, llamamos al método Arbiter.Choice (dentro del necesario Arbiter.Receive), e indicamos que si la operación se ha realizado satisfactoriamente se ejecuta el primer delegado, sino el segundo delegado para indicar que ha habido un error en el proceso.
|