Я решил рассмотреть функционал, связанный с асинхронными делегатами. В качестве примера рассмотрим ситуацию, когда используется интерфейс IAsyncResult, а также делегат AsyncCallback:
delegate void AsyncCallback(IAsyncResult). Делегат AsyncCallback используется для обработки результата, получаемого в результате выполнения асинхронного делегата. Т.е. вызываем делегат асинхронно, а через AsyncCallback получаем результат выполнения. Для этого в нем должен вызываться метод EndInvoke.
Я не буду подробно описывать BeginInvoke и EndInvoke, которые хорошо описаны на следующих ресурсах: http://msdn2.microsoft.com и на http://ondotnet.com. Отметим, что эти методы делегата генерируются автоматически для делегата. При этом BeginInvoke имеет параметры, которые совпадают с параметрами делегата. Последние два параметра метода BeginInvoke имеею типы AsyncCallback и object соответственно. Первый служит для регистрации метода обратного вызова, а параметр типа object служит для синхронизации и обмена данными.
Рассмотрим следующи пример кода:
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace asyncdeltest
{
// объявляем делегат
delegate string TestDelegate(string s);
class MainClass
{
private TestDelegate td;
// Функция получает строку и засыпает. Она возвратит нам новую строку, созданную на основе // переданной. Данную функцию мы зарегистрируем на делегате.
public string TestDelegateFunc(string s)
{
Thread.Sleep(5000);
return string.Format("Result string: {0}",s);
}
//Эта функция будет использоваться для получения результата выполнения асинхронного
//делегата, т.е. выполнения функции TestDelegateFunc, приведенной выше.
//Для передачи данных будем использовать поле sb, которое представляет собой объект типа
//StringBuilder. Получить этот объект можно через свойство AsyncState объекта AsyncResult.
// Отметим, что AsyncResult относится к пространству имен System.Runtime.Remoting.Messaging.
// Получитить результат выполнения функции TestDelegateFunc можно вызвав метод
//EndInvoke объекта Delegate, передав в него экземпляр типа IAsyncResult.
public void ResultFunc(IAsyncResult ar)
{
StringBuilder sb=(StringBuilder) ar.AsyncState;
AsyncResult ar1=(AsyncResult)ar;
TestDelegate td1=(TestDelegate)ar1.AsyncDelegate;
sb.Append(td1.EndInvoke(ar));
Console.WriteLine("In Result Func: "+sb.ToString());
}
private StringBuilder sb=new StringBuilder("Origin!");
//Этот метод будем использовать для вызова делегата асинхронно.
public void test()
{
td=new TestDelegate(TestDelegateFunc);
td.BeginInvoke("Test String",new AsyncCallback(ResultFunc),sb);
}
//Метод позволит нам получить содержимое объекта, используемого для обмена данными, т.е.
//поля класса типа StringBuilder.
public void atEnd()
{
Console.WriteLine("Result value: "+sb.ToString());
}
//Непосредственно сам тест. Вызываем делегат асинхронно. После этого уходим в сон
// и ожидаем результата. Проверку результата проводим методом atEnd.
public static void Main(string[] args)
{
MainClass mc=new MainClass();
mc.test();
Console.WriteLine("Before sleeping");
Thread.Sleep(10000);
Console.WriteLine("After sleeping");
mc.atEnd();
}
}
}
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий