Dos preguntas sobre el patrón de devolución de llamada con AsyncCallback y IAsyncResult.Dos preguntas sobre el patrón AsyncCallback y IAsyncResult
me cambió la pregunta con un ejemplo de código:
using System;
using System.Collections.Generic;
using System.Text;
namespace TestAsync
{
class Program
{
private static Wrapper test = new Wrapper();
static void Main(string[] args)
{
test.BeginMethod("parameter 1", "parameter 2", Callback);
Console.ReadKey();
}
private static void Callback(IAsyncResult ar)
{
string result = test.EndMethod(ar);
}
}
public interface ITest
{
IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state);
string EndMethod(IAsyncResult result);
}
public class Wrapper
{
private ITest proxy = new Test();
public void BeginMethod(string s1, string s2, AsyncCallback cb)
{
proxy.BeginMethod(s1, s2, cb, proxy);
}
public string EndMethod(IAsyncResult result)
{
return ((ITest)(result.AsyncState)).EndMethod(result);
}
}
public class Test : ITest
{
private string WorkerFunction(string a, string b)
{
// "long running work"
return a + "|" + b;
}
public IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state)
{
Func<string, string, string> function = new Func<string, string, string>(WorkerFunction);
IAsyncResult result = function.BeginInvoke(s1, s2, cb, state);
return result;
}
public string EndMethod(IAsyncResult result)
{
return (string)(result.AsyncState);
}
}
public delegate TResult Func<T1, T2, TResult>(T1 t1, T2 t2);
}
COMENZAR EDITAR
estoy empezando a ver lo que está pasando. He mezclado un patrón asíncrono WCF y un patrón asíncrono normal. En WCF uno usa un proxy y Begin- and EndMethod debe pasarse el proxy y no la función delegar. En el caso de WCF, el casting funciona, en el caso normal no. WCF usa el atributo [OperationContract (AsyncPattern = true)] probablemente para imponer un patrón algo diferente. FIN EDITAR
¿Por qué el error en la línea return (string)(result.AsyncState);
?
Exactamente el mismo patrón en el código de producción está bien.
En segundo lugar, ¿por qué no puedo depurar el código en BeginMethod of class Test?
Solo puedo romper en WorkerFunction.
Usted completa la función de delegado como el parámetro de estado 'object @ object' - ¿sabe si eso es obligatorio? – Gerard
En lugar de 'IAsyncResult result = function.BeginInvoke (...' podría simplemente hacer 'function.BeginInvoke (...'? – Gerard
Sí, siento que CallBack debería ser WorkerFunction. Voy a cambiar esto ahora. No es obligatorio rellene la función de delegado como el parámetro de estado @object. Sin embargo, como puede ver haciendo eso le da acceso al delegado dentro del cuerpo de la devolución de llamada. Debe llamar a un EndInvoke en el delegado desde la devolución de llamada para que necesite el delegado función de referencia. Y sí, simplemente puede hacer funcionar.BeginInvoke. Mantuve la muestra con la misma sintaxis que estaba usando realmente. Como puede ver, no reutilizo la variable "resultado" después de que el BeginInvoke – Nikhil