2-й BeginInvoke вызов претензий уже завершен. Зачем? - PullRequest
0 голосов
/ 23 сентября 2010

Я неоднократно вызываю метод с BeginInvoke. После каждого звонка я вызываю EndInvoke.

Проблема заключается в том, что для второго вызова элемент IsCompleted в возвращенном IAsyncResult устанавливается равным true НЕМЕДЛЕННО после вызова BeginInvoke.

Это вызывает сбой, потому что программа думает, что второй вызов завершен.

Почему это происходит, и как я могу определить, когда 2-ой звонок ДЕЙСТВИТЕЛЬНО завершен?

Declarations:
IAsyncResult ar;
Mercury.J4000.Ui.frmMain.doPrintsDelegate printCallback;


The BeginInvoke call:
ar = printCallback.BeginInvoke (jobNameArray, copies, distances, null, null);


The EndInvoke call (in another method):
printCallback.EndInvoke(ar);

Ответы [ 2 ]

2 голосов
/ 23 сентября 2010

Я предполагаю, что вы делаете что-то вроде этого:

IAsyncResult ar;
ar = printCallback.BeginInvoke(...);
// do some other stuff
ar = printCallback.BeginInvoke(...);

Если первая асинхронная операция не завершена до начала второй, вы потеряете значение IAsyncResult.Он перезаписывается вторым вызовом.

Каким-то образом вы должны отслеживать отдельные ссылки IAsyncResult и связывать их с выполненными вами вызовами.Если у вас есть только один или два, вы можете легко отслеживать отдельные переменные или коллекцию (List или массив, как правило).

Этот вопрос может вам помочь: Могу ли я использоватьодин экземпляр делегата для запуска нескольких асинхронных запросов?

Я также предлагаю рассмотреть возможность использования обратных вызовов для ваших асинхронных делегатов.Таким образом, правильный IAsyncResult передается в качестве параметра для обратного вызова, и нет никакой вероятности для двусмысленности.Однако использование AsyncCallback может потребовать серьезного рефакторинга вашего кода.

2 голосов
/ 23 сентября 2010

Я предполагаю, что вы используете одну и ту же переменную "ar" в обоих вызовах, потому что вы объявили ее как поле. Каждый вызов должен иметь свой собственный экземпляр; вместо этого объявите поле как List<IAsyncResult> и напишите необходимые данные для его инициализации и сопоставьте каждый результат с каждым вызовом. Вы не дали достаточно кода для нас, чтобы помочь вам с этой частью (на самом деле этот ответ является предположением, потому что вы не дали достаточно кода.)

...