包装异步java webservice调用

时间:2016-09-09 22:56:35

标签: c# web-services soap async-await

我正在编写一些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并且永远不会返回响应。当我测试/调用Sync版本时,我得到了预期的响应。这是我们多年来一直使用的网络服务,现在我们正在扩展C#方面的一些功能。

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

1 个答案:

答案 0 :(得分:0)

事实证明,在这种情况下,JAVA Web服务不会理解所有端点上的异步。我在VS中使用Microsoft的工具创建的所有端点中找到了2个异步端点。获得的经验:因为它被定义并不意味着它存在。