简体   繁体   English

如果我想返回WebClient的结果该怎么用

[英]What to use if i want to return the result of a webclient

take the following code: 采取以下代码:

    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 gets called... and response = the response I want... Great. WebClient_DownloadStringCompleted被调用...并且response =我想要的响应...很好。 perfect... 完善...

Now consider how i'm calling this AuthenticatedGetData method: 现在考虑我如何调用此AuthenticatedGetData方法:

It is being called from a kind of repository... The repository wants a string so that it can serialize and do stuff with the resulting object... 它是从一种存储库中调用的...存储库需要一个字符串,以便它可以序列化并对生成的对象进行处理...

So everything is running async fromt he repository... The call gets made to the authenticatedgetdata, it then makes a request... but because the downloadstringasync does not have a .Result() method and because downloadstringcompleted requires a void method to call... I cannot return the result string to the calling repository. 因此,所有内容都从存储库开始异步运行...对该身份验证的getdata进行了调用,然后发出了一个请求... ...但是,因为downloadstringasync没有.Result()方法,并且因为downloadstringcompleted需要调用void方法。 ..我无法将结果字符串返回到调用存储库。

Any ideas on what I must do to get client.DownloadStringAsync to return the response string on completion? 关于必须做什么才能获得client.DownloadStringAsync以在完成时返回响应字符串的任何想法?

Is it that I just simply have to tightly couple my data access operations to this specific app.. It seems so un..re-usable :( I really want to keep my whole authentication stuff totally separate from what's going to happen. and I do not want to keep repeating the above code for each repository, because it's going to be the same for each anyway! 是我只需要将我的数据访问操作紧密地耦合到该特定应用程序即可。.似乎是如此..可重复使用的:(我真的想使我的整个身份验证工作与即将发生的事情完全分开。不想为每个存储库重复上面的代码,因为无论如何它都一样!

Edit::// 编辑:://

I've created an abstract method in my class that deals with the above requests... and then I extend this class with my repository and implement the abstract method. 我在我的类中创建了一个抽象方法来处理上述请求...,然后用我的存储库扩展该类并实现抽象方法。 sound good? 听起来不错?

Edit:// Calling code as requested: 按要求编辑://呼叫代码:

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;
    }
}

I'm not sure what the windows-phone-8 limitations are with regards to this. 我不确定Windows Phone 8对此有何限制。 But I think this should work. 但是我认为这应该可行。

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;
    }

You might also be able to get away with this (not sure if it works on windows phone 8) 您也许也可以解决这个问题(不确定它是否可以在Windows Phone 8上运行)

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

    }

A solution is to not use the WebClient library at all. 一个解决方案是根本不使用WebClient库。 Here's the issue: you are awaiting your async AuthenticatedGetData Task, but it does nothing because the Task has no await calls in it meaning it will finish instantly. 问题出在这里:您正在等待异步的AuthenticatedGetData任务,但是它没有任何作用,因为该任务中没有等待调用,这意味着它将立即完成。 Calling the .result on the task will always be null because you can never return a value in that method. 在任务上调用.result始终为null,因为您永远无法在该方法中返回值。 The WebClient relies on calling a function call after the DownloadCompleted event is fired. 触发DownloadCompleted事件后,WebClient依赖于调用函数调用。 However, there is no way for anyone to know exactly when this happens, unless they also subscribe to that DownloadCompleted event handler, which is silly. 但是,除非有人也订阅那个DownloadCompleted事件处理程序,这是很愚蠢的,否则任何人都无法确切知道何时发生这种情况。 I recommend making a true async web request service using HttpWebRequest http://blogs.msdn.com/b/andy_wigley/archive/2013/02/07/async-and-await-for-http-networking-on-windows-phone.aspx good luck. 我建议使用HttpWebRequest http://blogs.msdn.com/b/andy_wigley/archive/2013/02/07/async-and-await-for-http-networking-on-windows-phone制作真正的异步Web请求服务.aspx祝您好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果我想在我的数据库中找到确切的搜索结果,我该用什么代替“FirstOrDefault()”? - What do I use in place of “FirstOrDefault()” if I want to find an exact search result in my database? 如果方法不是我想要的选项,它应该返回什么? - What should a method return if it is not an option I want? 我想对由三个不同数据表组成的数据表使用内连接,并使用 c# 作为合并数据表返回结果 - I want to use inner join on data table's consisting of three different data table and return result as consolidated data table using c # 如果搜索失败,我应该返回什么结果? - What result I should return for unsuccessfully search? 在使用WCF时,如何使用哪种数据结构返回使用FOR XML格式化的SQL Server查询结果? - In using WCF, What data structure do I use to return a SQL Server query result that is formatted using FOR XML? 如果我想返回整个响应,我的返回类型是什么 - What would my return type be if I want to return the whole response 异步任务<string>不返回正确的结果,WebClient.OpenReadTaskAsync()</string> - async Task<String> not return correct result,WebClient.OpenReadTaskAsync() 为什么我的 Web api 在使用 WebClient 类时返回状态代码 401,而在使用 HttpWebResponse 时返回状态代码 200? - Why my web api return Status code 401 when i use WebClient class and Status code 200 when i use HttpWebResponse? 一项行动的结果是什么,我如何使用它? - What is the result of an Action and how can I use it? 我可以通过WebClient读取iframe(我想要外部html)吗? - Can i read iframe through WebClient (i want the outer html)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM