2016-04-19 17 views
2

私はasyncを非同期的に待機して実装しています。私はC#4.6を使用しています。非同期待機ボタンは常に同期的に実行されます。

これで、async-awaitを追加した後、ページは常に同期して実行されます。 apiが結果を返すのを待っていて、メッセージを画面に表示します。

私が探しているのは、このページがスレッドを起動し、応答性があるということです(私は他のビットも使えます)。完了すると、結果が表示されます。

以下は、私のボタンクリック、HTTPコール(非同期reqを開始する)、およびAPIメソッドです。

私は

  1. を持っては例のStackOverflowや他のフォーラムで解決策を探したhttps://msdn.microsoft.com/en-us/library/hh191443.aspx
  2. を追いました。私はそれを(もちろん私は:(おりません)同じようにやっていると信じています。

追加Async="true" aspxページで。

ボタンをクリックし

protected async void btnCopy_Click(object sender, EventArgs e) 
    { 
     await RunAsync(Guid.Parse(SourceBusinessID), Guid.Parse(DestinationBusinessID), false); 

     if (lblError.Text == "") 
     { 
      lblError.Text = "Copy Completed!"; 
     }    
    } 

public async Task RunAsync(Guid SourceBusinessID, Guid DestinationBusinessID,bool copyAdviser) 
    { 
     using (var client = new HttpClient()) 
     { 
      var request = new HttpRequestMessage() 
      { 
       RequestUri = new Uri("http://localhost:52140/api/DummyAccounts/"), 
       Method = HttpMethod.Get, 
      }; 
      request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); 

      client.Timeout = TimeSpan.FromSeconds(500); 

      var response = await client.SendAsync(request); 

      if (!response.IsSuccessStatusCode) 
      {      
       lblError.Text = response.StatusCode.ToString(); 
      } 
     } 
    } 

API

public IHttpActionResult Get(Guid sourceBusinessID, Guid destinationBusinessID,bool copyAdviser = true) 
    { 
     try 
     { 
      CopyHelper.SourceBusinessID = sourceBusinessID; 
      CopyHelper.DestinationBusinessID = destinationBusinessID; 
      CopyHelper.CopyAdviser = copyAdviser; 

      logger.Info("Copy buisness started:" + DateTime.Now); 

      bool status = CopyBusinessService.CopyBusiness(CopyHelper.SourceBusinessID, CopyHelper.DestinationBusinessID, CopyHelper.CopyAdviser); 
      if (status) 
      { 
       logger.Info("Copy business finished:" + DateTime.Now); 

       return Ok(true); 
      } 
      else 
      { 
       logger.Info("Copy business failed:" + DateTime.Now); 

       return Ok(false); 
      } 
     } 
     catch (Exception ex) 
     { 
      return InternalServerError(ex); 
     } 

    } 

ご協力いただければ幸いです。

+4

私はあなたが少し混乱するかもしれないと思います。Stephen Clearyの[AsyncはHTTPプロトコルを変更しない](http://blog.stephencleary.com/2012/08/async-doesnt-change-http-protocol.html)を読むことをお勧めします。 –

+0

ありがとう@Damien_The_Unbeliever本当に役に立ちました。 – chunky

答えて

5

WebFormsアプリケーションでの非同期化は、フォームが座っているイベントとイベントループで動作するクライアントサイドアプリケーションのように振る舞いません。これは、WebフォームによってHTMLレスポンスがレンダリングされた単一のサーバーで、ボタンのクリックまたは変更イベントによってトリガーされる単一のトランザクションHTTPリクエストに応答する、サーバーレンダリングされたページです。レンダリングされると、ページが完了します。次回のクリックを待つイベントループはありません。

WebForms/ASP.NETアプリケーションのAsyncでは、メインスレッドから処理をオフロードすることができますが、ページ上のUIの動作は変更されません。 asyncを複数の操作を同時に実行する方法と考えてください。また、長い実行中のIO操作がバックグラウンドで実行されている間にメインの処理スレッドを解放してから、最後のページがレンダリングされる前に戻ります。

しかし、ページがブラウザに実際にレンダリングまたは動作する方法は何もしません.WebFormsページは依然としてHTTPポストバックによるイベントを処理する純粋なサーバーレンダリングページです。ブラウザーに関する限り、トランザクション要求です。ボタンをクリックすると、バックエンドで非同期を使用するかどうかに関係なく、ページが再レンダリングされます。

問題を解決する方法は、クライアントサイドのJSフレームワークを使用してアプリケーションの非同期フローを管理し、サーバーにasynch HTTP呼び出しを行うことです。そうすれば、探している振る舞いが得られます。クライアント側のアプリケーションに他の操作を継続させながら、「バックグラウンドで」実行できる長いリクエストがあります。サーバーは、操作が完了したときに最終的にあなたを呼び出し、応答データを使用して結果を表示したり、ユーザーに通知したりすることができます。

+0

ありがとう@Rickおそらくjsフレームワークに移ります。私のボタンクリックイベントでRunAsync(Guid.Parse(SourceBusinessID)、Guid.Parse(DestinationBusinessID)、false);を待ってから 'await'を削除すると、メソッドは同期を実行し、他のものを実行できますapiはバックグラウンドで作業しています。しかし、APIが仕事を終えると、何らかの形で主要なワーカープロセスが終了します。私はその後、私のソリューションを再構築して、もう一度始めなければなりません。私の主な仕事のプロセスがなぜ死んだのか分かりません。 – chunky

+0

ASYNC操作でAWAITを削除することはできません。まだ実行されますが、非同期で実行され、待機しません。あなたのリクエストは終了し、Aysncの操作が何をしていたとしても、ページはもはやそこになく、そして - BOOMであることがわかります。もう一度、サーバーのASYNCがどのように機能するかを少し読んでみる必要があります。クライアント側とサーバー側の非同期機能を混乱させ、問題が発生することを理解するまでは、 –

-2

は、私はあなたがこのような何かをする必要があると思う:

private void btnCopy_Click (object sender, RoutedEventArgs e) 
    { 
     Task.Factory.StartNew(async() => 
     { 
      await RunAsync (Guid.Parse (SourceBusinessID), Guid.Parse (DestinationBusinessID), false); 
      lblError.Dispatcher.Invoke(() => { if (lblError.Text == "") lblError.Text = "Copy Completed!"; }); 
     }); 
    } 
関連する問題