Прежде всего, вы всегда должны вызывать соответствующий метод EndXXX для любого метода BeginXXX.
Затем вы должны убедиться, что не утилизируете объект, который вызываете метод BeginXXX, прежде чем вызывать метод EndXXX.
Подход "сохранить и забыть" (игнорируя проблему утилизации) заключается в передаче EndXXX в качестве обратного вызова BeginXXX:
obj.BeginXXX(callback: obj.EndXXX, state: null);
// -- or --
obj.BeginXXX(callback: asyncResult => obj.EndXXX(asyncResult), state: null);
Вам все еще нужно убедиться, что вы не вызываете obj.Dispose();
до завершения всех асинхронных операций.