Как вызвать асинхронный метод wcf в использовании оператора?

В синхронной модели это просто

using (MyServiceClient msc = new MyServiceClient())
{
   msc.Method();
}

но если я должен подождать до конца этого метода, а затем сделать что-то, это не может работать

private void EventHandler<MethodCompletedEventArgs> myEventHandler = new EventHandler<MethodCompletedEventArgs>(methodBody);

using (MyServiceClient msc = new MyServiceClient())
{
   msc.MethdCompleted += myEventHandler;
   msc.BeginMethod();
}

private void MethodBody()
{
//exception: client state is aborted
}

Также как вызвать асинхронный метод в using заявление?

2 ответа

Решение

Вы можете сохранить ссылку на ваш сервисный клиент и вручную вызвать его Dispose метод, как только событие перезванивает. Вам просто нужно проделать дополнительную работу, управляя исключениями и в целом гарантируя, что Dispose называется в конце концов. Также следите за условиями, в которых вы можете создать / перезаписать несколько экземпляров msc в ожидании завершения старого:

Один из способов убедиться, что вы не избавляетесь от неправильного экземпляра, если выполняете один и тот же код несколько раз, - это использовать локальную лямбда / анонимную функцию:

MyServiceClient msc = new MyServiceClient();

msc.MethdCompleted += (sender, args) => 
{
    try
    {
        myEventHandler(sender, args);
    }
    finally
    {
        msc.Dispose();
    }
};

msc.BeginMethod();

Это может стать немного грязнее, чем это; если возникло исключение msc.BeginMethod() Вы должны также поймать это и позвонить Dispose скорее всего (но вы не хотите звонить Dispose больше чем единожды)

Вы не должны этого делать.

Вы должны создать экземпляр MyServiceClient нормально тогда Dispose об этом в обработчике асинхронного обратного вызова.

Это единственный способ убедиться, что экземпляр будет существовать после вызова обработчика обратного вызова и что он будет уничтожен после того, как обработчик обратного вызова завершит свою работу.

Другие вопросы по тегам