Usted no está obligado a llamar EndInvoke
; no llamarlo meramente significa:
- No obtiene el valor de retorno del método.
- Cualquier excepción lanzada durante la ejecución del método simplemente desaparecerá.
Parece que usted quiere 'dispara y olvida', por lo que la forma más fácil de hacer esto es utilizar un delegado en el anonimato, por ejemplo:
var del = new Action(foo.Bar);
del.BeginInvoke(iar =>
{
try
{
del.EndInvoke(iar);
}
catch (Exception ex)
{
// Log the message?
}
}, null);
Esto es lo que sucede cuando se ejecute este código:
- Un nuevo hilo se asigna (en pocas palabras) para el delegado.
- El hilo se le da al delegado
del
y el delegado anónimo (iar => ...
).
- El hilo ejecuta
del
.
- Cuando termina de ejecutarse (o se produce una excepción), el resultado o la excepción se almacena y se ejecuta el delegado anónimo.
- Dentro del delegado anónimo, cuando se llama
EndInvoke
, se devuelve el resultado del método o se produce la excepción (si se produjo).
Tenga en cuenta que el ejemplo anterior es muy diferente de:
// This is pointless and is still, essentially, synchronous.
del.EndInvoke(del.BeginInvoke(null, null));
Editar: siempre debe llamar End*
. Nunca he encontrado un escenario donde no llamarlo presenta un problema, sin embargo, eso es un detalle de implementación y es relying on undocumented behavior.
Finalmente su solución bloquearía el proceso si se lanza una excepción,
simplemente puede pasar nulo como delegado si no le importa la excepción (
del.BeginInvoke(myStruct, null, null);
).
Así como un ejemplo final lo que busca es probablemente:
public class A
{
// ...
void Foo(S myStruct){...}
void FooAsync(S myStruct)
{
var del = new Action<S>(Foo);
del.BeginInvoke(myStruct, SuppressException, del);
}
static void SuppressException(IAsyncResult ar)
{
try
{
((Action<S>)ar.AsyncState).EndInvoke(ar);
}
catch
{
// TODO: Log
}
}
}
Es cierto que usted no es "necesaria" para llamar 'EndInvoke', pero si don Tendrás filtraciones de memoria. http://stackoverflow.com/questions/1712741/why-does-asynchronous-delegate-method-require-calling-endinvoke?rq=1 –
@MattKlein no, no es así. https://gist.github.com/jcdickinson/9109599. La respuesta de SLaks es algo correcta, sin embargo, en ciertos escenarios se realiza un seguimiento con pares 'Begin/End-Invoke' - un ejemplo es: si no llamas' EndInvoke' en las operaciones 'Socket' tus contadores de rendimiento de socket se apagarán por completo fuera de sintonía (sin pérdida de memoria, los valores serán simplemente muy incorrectos). –
Quizás este sea un comentario valioso para agregar a la respuesta de SLaks. –