Недостатки синхронного вызова веб-службы внутри асинхронного метода

1

Я работаю над проектом, который должен создать XML с определенными данными в определенном формате, отправить его сторонней службе и затем обработать результат. Третья функция здесь состоит в том, чтобы проверить как данные, так и формат XML, а затем создать кодифицированную строку ("штамп"), подтверждающую, что все соответствует запросам. Затем эта марка должна быть добавлена в исходный XML и храниться в базе данных.

Теперь третья сторона по-прежнему должна быть выбрана, поэтому я должен создать свой проект таким образом, чтобы он работал (до сих пор) двумя различными веб-сервисами до выпуска, с возможностью добавления другого и после выпуска изменения Выбранный. Хотя конечный результат один и тот же ("тиснение" XML), каждый веб-сервис выполняет разные действия, например, возвращает только строку штампа, в то время как другая возвращает XML с включенной печатью, а ожидающий возвращает массив байтов zip файл, содержащий XML (я не знаю, кто сказал им, что это хорошая идея, но meh, эта другая история)

Имея это в виду, я решил создать статический класс, который обертывает вызовы веб-сервисов (один метод для каждой веб-службы). Все эти методы получают XML и возвращают либо "штампованный" XML, либо XML с кодом ошибки и сообщением в случае, если что-то пошло не так. Класс, который обрабатывает данные, должен только создать необходимый XML, вызвать один из этих методов и обработать результат.

Пока это выглядит примерно так:

public class EDocument
{
    //This class handles all the data that will be included in the XML

    public void Stamp()
    {
        //Here the XML string is created, sent to the correspondig third-party web service, and processed back

        string xmlString;
        //code to create the XML
        //...

        //If needed, I only have to change this line to call the corresponding method
        WebServiceCalls.MainWebServiceCall stamper = WebServiceCalls.FirstServiceCall;
        stamper.BeginInvoke(xmlString, StampCallback, null);
    }

    public void StampCallback(IAsyncResult ar)
    {
        AsyncResult result = (AsyncResult)ar;
        WebServiceCalls.MainWebServiceCall caller = (WebServiceCalls.MainWebServiceCall)result.AsyncDelegate;
        string response = caller.EndInvoke(ar);
        //Call another async method to save to database the stamp, create the XML file, e-mail and store it, and notify the results...
        //or create the exception with the error details and raise event here to notify the error
    }
}

Веб-службы звонков...

public static class WebServiceCalls
{
    //Here I'll put the necessary web service calls. In the end there will be only one,
    //but if on future the web service changes, a method with the same signature will be created here
    //replacing the previous one

    public delegate string MainWebServiceCall(string XmlData);

    public static string FirstServiceCall(string XmlData)
    {
        FirstWebService firstWs = new FirstWebService();
        string serviceResult = firstWs.Stamp(XmlData); //This returns only the stamp string
        //Check the result, add the stamp to the original XML or create the error XML, and return...
        return serviceResult;
    }

    public static string SecondServiceCall(string XmlData)
    {
        SecondWebService secondWs = new SecondWebService();
        string serviceResult = secondWs.Stamp(XmlData); //This returns the XML with the stamp already added
        //Check the result, create the error XML if something went wrong, and return...
        return serviceResult;
    }

    public static string ThirdServiceCall(string XmlData)
    {
        ThirdWebService thirdWs = new ThirdWebService();
        string serviceResultString;
        byte[] serviceResult = thirdWs.Stamp(XmlData); //This (sigh) returns the byte array of a ZIP file...
        //Unzip the file, check the result, create the corresponding XML and return...
        return serviceResultString;
    }
}

Но потом он ударил меня... Хотя я буду асинхронно вызывать методы обёртки, метод веб-службы все равно будет вызываться синхронно.

Вопрос в том, каковы недостатки этого? следует ли я вместо этого асинхронно обращаться к веб-службе по каждому методу вызова, обрабатывать обратный вызов, поднять уведомление, ухватить его в классе Edocument, обработать результат и поднять его соответствующее событие? Разве это не осложняло бы рассмотрение возможных будущих изменений этого проекта?

Или это общий неправильный подход к проблеме?

Имейте в виду, что это С# 4.0, поэтому (к сожалению) асинхронный ожидания выходит за рамки.

Теги:
asynchronous

1 ответ

1

Вы не используете async IO вообще. Delegate.BeginInvoke использует пул потоков. В серверных приложениях это практически повредит практически во всех ситуациях. Async IO не имеет потоков.

Используйте синхронный код или асинхронный ввод-вывод.

Кажется, вы думаете, что асинхронное обращение к веб-сервису, которое внутренне синхронно (или наоборот), может иметь недостаток. Это не тот случай. Ни одна из сторон не может даже сказать, как реализуется другая. Переход на асинхронный уровень в определенном уровне влияет только на этот уровень.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню