Не удается преобразовать IAsyncResult в AsyncResult при использовании ссылки на службу - PullRequest
2 голосов
/ 12 марта 2010

У меня запущена служба WCF, я добавил ссылку на службу с помощью Добавить ссылку на службу в обозревателе решений и установил флажок для создания асинхронных операций.

Мой звонок работает нормально, у меня есть двухсторонний канал, который сообщает о некоторых событиях с сервера, и я получаю события. Однако, когда асинхронная задача заканчивается в моем обработчике обратного вызова, я получаю ошибку Unable to cast object of type 'SendAsyncResult' to type 'System.Runtime.Remoting.Messaging.AsyncResult'.

Код, который вызывает метод.

DatabaseManagement.DatabaseManagementClient d = new DatabaseManagement.DatabaseManagementClient(new InstanceContext(new DatabaseManagementCallback()));
d.Open();
d.BeginCreateDatabase("", "PreConfSA", "_test", new AsyncCallback(BeginCreateDatabaseCallback), null);

Асинхронный обратный вызов

static void BeginCreateDatabaseCallback(IAsyncResult ar)
{
    AsyncResult result = (AsyncResult)ar; //Execption happens here
    DatabaseManagement.DatabaseManagementClient caller = (DatabaseManagement.DatabaseManagementClient)result.AsyncDelegate;
    Console.WriteLine(caller.EndCreateDatabase(ar));
    DatabaseManagement.AccountInfo ai = new DatabaseManagement.AccountInfo();
    //set up ai here
    Console.WriteLine(caller.UpdateInfo("", "_test", ai));
}

Сведения об исполнении

System.InvalidCastException was unhandled by user code
  Message=Unable to cast object of type 'SendAsyncResult' to type 'System.Runtime.Remoting.Messaging.AsyncResult'.
  Source=Sandbox Console
  StackTrace:
       at Sandbox_Console.Program.BeginCreateDatabaseCallback(IAsyncResult ar) in E:\Visual Studio 2010\Projects\Sandbox Console\Program.cs:line 26
       at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
  InnerException: 

Мне действительно не нужен результат из EndCreateDatabase, но везде, где я читаю, говорится, что вы должны вызывать EndYouFunctionHere (), иначе произойдут плохие вещи.

Есть рекомендации?

1 Ответ

4 голосов
/ 12 марта 2010

Методы EndXxx, сгенерированные для ссылки на сервис, имеют подпись:

EndXxx(IAsyncResult result);

(По крайней мере, они в моей среде - вы видите что-то другое?)

Таким образом, вам на самом деле не нужно выполнять приведение для вызова метода EndXxx.

Однако в этом случае вам do нужен какой-то способ получить ссылку на службу (экземпляр клиента) в метод обратного вызова, потому что вы не можете получить его с помощью AsyncResult.AsyncDelegate. Вы можете сделать это либо путем сохранения прокси-объекта в переменной-члене вместо локальной переменной, либо передать его методу BeginXxx как asyncState:

d.BeginCreateDatabase("", "PreConfSA", "_test",
  new AsyncCallback(BeginCreateDatabaseCallback),
  d);  // passing d as asyncState instead of null

Затем извлеките его из IAsyncResult.AsyncState в обратном вызове:

DatabaseManagement.DatabaseManagementClient caller =
  (DatabaseManagement.DatabaseManagementClient)ar.AsyncState;

Это исключает любые предположения о конкретной реализации IAsyncResult.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...