#vb.net #web-services #asynchronous
#vb.net #веб-службы #асинхронный
Вопрос:
Я делаю VB.NET приложение, которое использует веб-службу SOAP. Он очень хорошо работает в синхронном режиме с использованием метода run. Но я хотел бы использовать этот асинхронный метод :
Public Overloads Sub runAsync(ByVal callContext As CAdxCallContext, ByVal publicName As String, ByVal inputXml As String, ByVal userState As Object)
If (Me.runOperationCompleted Is Nothing) Then
Me.runOperationCompleted = AddressOf Me.OnrunOperationCompleted
End If
Me.InvokeAsync("run", New Object() {callContext, publicName, inputXml}, Me.runOperationCompleted, userState)
End Sub
Как его вызвать?
Как указать метод обратного вызова?
Спасибо
Piotr
Комментарии:
1. Что не так с предоставленным вами примером кода.
Me.runOperationCompleted
это был бы метод обратного вызова.
Ответ №1:
TaskCompletionSource
было бы правильным инструментом для объединения методов, основанных на событиях, с асинхронным.
Создайте обработчик события завершения, который принимает экземпляр TaskCompletionSource
в качестве аргумента.
Public Sub OperationCompleted(
e As SomeEventArgs,
TaskCompletionSource(Of SoapResult) taskSource
)
' Use EventArgs of your client to determine were operation successful or not
' Here I am using common completion properties
If e.Cancelled Then
taskSource.TrySetCanceled()
Exit Sub
End If
If e.HasError Then
taskSource.TrySetException(e.Error)
Exit Sub
End If
' Should be success now
taskSource.TrySetResult(e.Result) ' Result is an instance of type SoapResult
End Sub
Асинхронный метод возвращает задачу, в этом примере мы ожидаем, что экземпляр типа o SoapResult
будет возвращен при успешном выполнении операции.
Public Function RunAsync(MyInputArguments args) As Task(Of SoapResult)
Dim taskSource As New TaskCompletionSource(Of SoapResult)()
Dim invokeArgs As New Object() { args.Context, args.PublicName, args.InputXml }
' Wrap our completion handler with the function
' To satisfy soap callback signature
Dim callback As Action(Of SomeEventArgs) =
Sub(e) Me.OperationCompleted(e, taskSource)
InvokeAsync("run", invokeArgs, callback, args.UserState)
Return taskSource.Task
End Function
Теперь мы можем асинхронно вызывать Soap-клиент с async-await
Dim arguments As New With
{
.Context = callContext,
.PublicName = publicName,
.InputXml = inputXml,
.UserState = userState
}
Dim result As SoapResult = Await client.RunAsync(arguments)
Ответ №2:
Спасибо за вашу помощь, это навело меня на правильный путь.
Я нашел, как вызвать и получить обратный вызов, используя асинхронный метод :
вызов :
x3WebService.runAsync(callContext, webserv, params, UserState)
обратный вызов :
Public Sub RunAsyncCompleted(sender As Object, e As runCompletedEventArgs) Handles x3WebService.runCompleted
…
Но вы должны объявить «withevents» в классе x3WebService :
Public Class X3WebServices
Private WithEvents x3WebService As CAdxWebServiceXmlCCServiceBasicAuth
Доброго вам дня,
Piotr