И вызов EndInvoke не является дополнительным вызовом, это - часть контракта. При вызове BeginInvoke, необходимо назвать EndInvoke.
Классический пример того, почему это необходимо. Очень возможно, что IAsyncResult, возвращенный из BeginInvoke, выделил ресурсы, присоединенные к нему. Обычно своего рода WaitHandle. Поскольку IAsyncResult не реализует IDisposable, другое место должно быть выбрано для освобождения ресурсов. Единственным местом, чтобы сделать так является EndInvoke.
я кратко обсуждаю эту проблему в следующем сообщении в блоге.
http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx
Для этого класса
public abstract class MyAbstraction
{
public virtual string Foo
{
get { return "foo"; }
}
}
вы можете настроить Foo (свойство только для чтения) следующим образом:
var stub = new Mock<MyAbstraction>();
stub.SetupGet(x => x.Foo).Returns("bar");
stub.Object.Foo
теперь будет возвращать «bar» вместо «foo».