包装异步java web服务调用

本文关键字:服务 调用 web java 异步 包装 | 更新日期: 2023-09-27 18:06:36

我正在编写一些c#代码来调用基于SOAP的Java语言web服务。当我从wsdl创建内部类时,我得到的结果是每个同步端点都有一个异步版本。到目前为止,我忽略了这些,因为还不需要异步调用。长话短说——现在有这样的需要。

下面是我尝试过的一个例子和(MS)单元测试来测试它:

public class Lookups : IWebRepository
{
    private readonly WebService _ws;
    public Lookups()
    {
        _ws = WebServiceExtended.Instance.Endpoint;
    }
    public IEnumerable<string> Cities() => _ws.getLookupList("Cities").Select(o => o as lookup).Select(l => l.Name);
    public async Task<IEnumerable<string>> CitiesAsync()
    {
        var results = await _ws.LookupAsync("Cities");
        return results.Result.Select(o => o as lookup).Select(a => a.Name);
    }
}

我创建这个扩展:

internal static class WebServiceAsyncExtensions
{
    internal static Task<getLookupListCompletedEventArgs> LookupAsync(this WebService ws, string lookupKey)
    {
        var taskCreateSource = CreateSource<getLookupListCompletedEventArgs>(null);
        ws.getLookupListCompleted += (sender, e) => TransferCompletion(taskCreateSource, e, () => e, null);
        ws.getLookupListAsync(lookupKey);
        return taskCreateSource.Task;
    }
    private static TaskCompletionSource<T> CreateSource<T>(object state) => new TaskCompletionSource<T>(state, TaskCreationOptions.None);
    private static void TransferCompletion<T>(TaskCompletionSource<T> taskCreateSource, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler)
    {
        if (e.UserState != taskCreateSource)
            return;
        if (e.Cancelled)
            taskCreateSource.TrySetCanceled();
        else if (e.Error != null)
            taskCreateSource.TrySetException(e.Error);
        else
            taskCreateSource.TrySetResult(getResult());
        unregisterHandler?.Invoke();
    }
}

和测试:

[TestMethod]
public async Task Lookup_Async_Cities_Succeeds()
{
    var response = await _ws.RepositoryLookups.CitiesAsync();
    Assert.IsInstanceOfType(response, typeof(IEnumerable<string>));
    Assert.IsTrue(response != null);
    Assert.IsTrue(response.Any());
}
查看生成的(wsdl)代码,我看到如下:
/// <remarks/>
public void getLookupListAsync(string arg0) {
    this.getLookupListAsync(arg0, null);
}
/// <remarks/>
public void getLookupListAsync(string arg0, object userState) {
    if ((this.getLookupListOperationCompleted == null)) {
        this.getLookupListOperationCompleted = new System.Threading.SendOrPostCallback(this.OngetLookupListOperationCompleted);
    }
    this.InvokeAsync("getLookupList", new object[] {
                arg0}, this.getLookupListOperationCompleted, userState);
}

我遇到的挑战是,当我进行调用时,它只是旋转到la la land并且从不返回响应。当我测试/调用同步版本时,我得到了预期的响应。这是一个我们已经使用多年的web服务,现在我们在c#方面扩展了一些功能。

我错过了什么吗?更好的是;我错过了什么?!

包装异步java web服务调用

在这种情况下,JAVA Web Service并不理解所有端点上的异步。我发现,在微软的工具在vs中创建的所有端点中,有2个端点是异步的。经验教训:因为它是定义的,并不意味着它存在。