2016-07-21 12 views
1

進行中で、私はそうHttpPost方法が背景 とcalling methodで実行する必要が供給URLからウェブResponseメッセージを待ちたくない場合はここで私はそのタスクを実行する必要があり、それが移行される場合propertieのチェックまたは進行中です同時に。 この機能を実現するために、以下の方法でasyncawaitを使用しました。以下は C#でasyncとawaitを使用するには?

は、ポストとバックURLから XML応答を得るための方法である:

public static async Task<string> HttpPost(string url, string message, bool ignoreResponse = false) 
{ 
    string lcPostData = null; 
    string _XmlResponse = string.Empty; 
    try 
    {    
     using (var client = new HttpClient()) 
     { 
      var httpContent = new StringContent(message, Encoding.UTF8, "application/xml"); 
      var SupplierLinkUri = new Uri(url); 

      if (!ignoreResponse) 
      {      
       var httpResponseMessage = await client.PostAsync(SupplierLinkUri, httpContent); 

       if (httpResponseMessage.StatusCode == HttpStatusCode.OK) 
        _XmlResponse = httpResponseMessage.Content.ReadAsStringAsync().Result; 
      } 
      else if (ignoreResponse && !(isReservation(message))) //message.Contains("Reservation")) 
      {  
       /* I want below lines of code to run asynchronously (i.e. Run in background) So I used Task & await but it fails*/ 
       Task<HttpResponseMessage> httpPostTask = client.PostAsync(SupplierLinkUri, httpContent); 
       HttpResponseMessage asyncPost = await httpPostTask;     
      } 
     }  
    } 
    catch (Exception e) 
    {  
    } 
    return _XmlResponse; 
} 

は、上記の方法はエラーなしで実行されているが、私は、これはC#でasyncawaitを使用するための適切なアプローチであるかどうかを知りたいです、 コードを修正する必要がありますか?

awaitelse-if部分が機能していません。ドキュメントごとに、これはasynchronouslyをバックグラウンドで実行する必要がありますが、現在はバックグラウンドではありません。

誰でもコード内の何が間違っているか確認してください。

これを達成するためのより良い方法はありますか?

おすすめのアイデアがあります。助けてくれてありがとう!

+0

:前の記事で非同期のボイド」を避けますサーバーコードが変更されていない限り、データを連続データとして取得することはできません。ブロック内のデータを取得する方が、メモリ例外が発生する可能性のある大きなデータブロックを取得するよりも、おそらく効率的です。巨大なXMLファイルは、しばしばメモリ例外を引き起こします。そして、あなたは今、それをやっているやり方でブロック内のxmlを効果的に読み取るxmlreaderを使う必要があります。 – jdweng

+0

ここで何をしようとしていますか?問題は何ですか?タスクが返された後まで、このメソッドからの応答が得られないという問題がある場合は、それが予想されます。 – Paddy

+0

@Paddy:問題は、ドキュメントごとにバックグラウンドで 'client.PostAsync(SupplierLinkUri、httpContent);'を実行するために 'await'を使用していますが、同期的に実行されています。 –

答えて

-1

OK - これはasync/awaitのためのものではありません - あなたが呼び出すメソッドは別のスレッド(UIスレッドではなく)で実行され、メインメソッドに制御を返します。背景)。

「待っている」メソッドは、非同期呼び出しが完了するまで結果を返しません。

上記の例では

async Task<int> A() 
{ 
    return await B(); 
} 

async Task<int> B() 
{ 
    //Call to a long running service to get your answer, e.g. 
    return await PostToClientAsynchronously(); 
} 

//Event handler on front end. 
async void SomeButton_Click() { 
    txtBox1.Text = await A(); 
} 

PostToClientAsynchronouslyは、別のスレッド(ないUIスレッド)上で実行されますが、コントロールは、ポストが完了するまで、イベントハンドラでテキストボックスの値を設定するためには戻りません。

あなた自身のコードの例を掲載したいと思いますが、完全に正直なところ、何をしたいのかは分かりません。私はあなたのUIに非同期メソッドを拡張することで問題を解決できると思うので、それをブロックしたり他の操作を許可したりすることはできませんが、わかりません。

async/awaitメソッドを呼び出す際のもう1つの重要な点は、正しい待機を可能にするために、(フロントエンドからの)すべてのメソッドを非同期としてマークする必要があることです。


あなたは型のメソッドとしてこれらを実行して「火と忘れる」しようとしているようですね、しかし、あなたがやっていることは、あなたが、その後に作用するために必要な情報や場所を返さないとき、これらはだけは本当に何かいいです起こりうる例外がアプリケーションに損害を与えることはないと確信しています。発生したすべての例外は、アプリケーションにバブルバックされません。

実際の火災と忘れの使用例はまれです。


非同期プログラミングするとき、それは「すべての方法ダウンカメ」でなければなりません理由に関するさらに詳しい情報:

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

火災についての詳しい情報や忘れては(あなたが」に関するセクションを読ん作りますあなたはブロックでXMLを取得している場合は

Fire and Forget approach

+0

詳細な説明をお寄せいただきありがとうございます! –

+0

'await'はバックグラウンドスレッド上でメソッドを実行せず、必ず元のスレッドで再開する必要はありません(この場合、一般的に*は*ではありません)。また、ASP.NETアプリケーションにUIスレッドはありません。 –

+0

@StephenCleary - 申し訳ありませんが、この呼び出しが行われた場所についての投稿は明確ではありませんでした。私は、ASP.netにUIスレッドが存在しないことを認識しており、同じスレッドで再開することは言及していません。 – Paddy

関連する問題