0

采取以下代码:

    public async Task<string> AuthenticatedGetData(string url, string token)
    {
        WebClient client = new WebClient();
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(WebClient_DownloadStringCompleted);
        client.DownloadStringAsync(new Uri(url + "?oauth_token=" + token));
    }

    private void WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        string response = e.Result;    
    }

WebClient_DownloadStringCompleted 被调用...并且响应 = 我想要的响应...太好了。完美的...

现在考虑我如何调用这个 AuthenticatedGetData 方法:

它是从一种存储库中调用的...存储库需要一个字符串,以便它可以序列化并处理结果对象...

所以一切都从存储库异步运行......调用是对authenticatedgetdata进行的,然后它发出请求......但是因为downloadstringasync没有.Result()方法并且因为downloadstringcompleted需要调用void方法。 .. 我无法将结果字符串返回到调用存储库。

关于我必须做什么才能让 client.DownloadStringAsync 在完成时返回响应字符串的任何想法?

是不是我只需要将我的数据访问操作与这个特定的应用程序紧密结合起来。它看起来如此不可重用:(我真的想让我的整个身份验证内容与将要发生的事情完全分开。我不想为每个存储库重复上述代码,因为无论如何它都将是相同的!

编辑:://

我在我的类中创建了一个处理上述请求的抽象方法......然后我用我的存储库扩展了这个类并实现了抽象方法。听起来不错?

编辑://按要求调用代码:

public class OrganisationRepository
{
    PostRequest postRequest;

    public OrganisationRepository()
    {
        this.postRequest = new PostRequest();
    }
    public IEnumerable<Organisation> GetAll()
    {
        string requestUrl = BlaBla.APIURL + "/org/";
        string response = postRequest.AuthenticatedGetData(requestUrl, BlaBla.Contract.AccessToken).Result;
    }
}

public class PostRequest
{

    public Task<string> AuthenticatedGetData(string url, string token)
    {

        TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();

        WebClient client = new WebClient();
        client.DownloadStringCompleted += (sender, e) =>
        {
            if (e.Error != null)
            {
                tcs.TrySetException(e.Error);
            }
            else if (e.Cancelled)
            {
                tcs.TrySetCanceled();
            }
            else
            {
                tcs.TrySetResult(e.Result);
            }
        };
        client.DownloadStringAsync(new Uri(url + "?oauth_token=" + token));
        return tcs.Task;
    }
}
4

2 回答 2

1

我不确定 windows-phone-8 对此的限制是什么。但我认为这应该有效。

public Task<string> AuthenticatedGetData(string url, string token)
    {
        TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();

        WebClient client = new WebClient();
        client.DownloadStringCompleted += (sender, e) =>
        {
            if (e.Error != null)
            {
                tcs.TrySetException(e.Error);
            }
            else if (e.Cancelled)
            {
                tcs.TrySetCanceled();
            }
            else
            {
                tcs.TrySetResult(e.Result);
            }            
        };
        client.DownloadStringAsync(new Uri(url + "?oauth_token=" + token));
        return tcs.Task;
    }

您也许也可以摆脱这个(不确定它是否适用于 Windows Phone 8)

public Task<string> AuthenticatedGetData(string url, string token)
    {
        WebClient client = new WebClient();
        return client.DownloadStringTaskAsync(new Uri(url + "?oauth_token=" + token));

    }
于 2013-09-30T22:43:34.863 回答
-1

一个解决方案是根本不使用 WebClient 库。这是问题所在:您正在等待异步 AuthenticatedGetData 任务,但它什么也不做,因为任务中没有等待调用,这意味着它将立即完成。在任务上调用 .result 将始终为 null,因为您永远无法在该方法中返回值。WebClient 依赖于在触发 DownloadCompleted 事件后调用函数调用。但是,任何人都无法确切知道何时发生这种情况,除非他们也订阅了 DownloadCompleted 事件处理程序,这很愚蠢。我建议使用 HttpWebRequest http://blogs.msdn.com/b/andy_wigley/archive/2013/02/07/async-and-await-for-http-networking-on-windows-phone制作真正的异步 Web 请求服务.aspx祝你好运。

于 2013-10-03T05:45:42.013 回答