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 を取得して完了時に応答文字列を返すために何をしなければならないかについてのアイデアはありますか?

データアクセス操作をこの特定のアプリに密接に結合する必要があるだけですか..再利用できないようです:(私は本当に、認証全体を何が起こるかから完全に分離したいと思っています.そして私はリポジトリごとに上記のコードを繰り返し続けたくありません。とにかく、それぞれ同じになるからです!

編集:://

上記のリクエストを処理するクラスに抽象メソッドを作成しました...そして、このクラスをリポジトリで拡張し、抽象メソッドを実装します。いいね?

Edit://要求に応じてコードを呼び出します:

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

解決策は、WebClient ライブラリをまったく使用しないことです。問題は次のとおりです。非同期の AuthenticatedGetData タスクを待っていますが、タスクに await 呼び出しがないため何もしません。つまり、すぐに終了します。タスクで .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 に答える