1

これは私のコードですが、非同期関数の呼び出しを開始した後はアプリが応答しなくなるため、他のことはできないようです。バックグラウンドで実行したいのですが。

私は検索をしています、そして、3文字ごとに、それが一致するならば、それはデータを得るためにAPIを呼びます。 3文字入力すると、それがAPIを呼び出し、アプリが応答していないため、それ以上入力できませんでした。

非同期機能を呼び出す方法と私はまだ検索できるようにバックグラウンドで実行されます。

void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
     var newText = e.NewTextValue;
     //once 3 keystroke is visible by 3
     if (newText.Length % 3 == 0)
     {
          //Call the web services
          var result = GettingModel(newText);
          if (result != null || result != string.Empty)
          {
               ModelVIN.Text = result;
          }    
     }
}

private string GettingModel(string vinText)
{
      var task = getModelForVIN(vinText);
      var result = task.Result;    
      return result.Model;
}

private async Task<VINLookUp> getModelForVIN(string vinText)
{
      var deviceId = CrossDeviceInfo.Current.Model;
      deviceId = deviceId.Replace(" ", "");
      var requestMgr = new RequestManager(deviceId);

      var VinData = new VINLookUp();    
      VinData = await requestMgr.getModelForVIN(vinText);    
      return VinData;
}

助けてくれてありがとう。


  • 単にあなたのイベントハンドラを非同期のイベントハンドラに変更してください、すなわち `async void Entry_TextChanged(){...; var result = await getModelForVIN()...;}' - Panagiotis Kanavos

1 답변


3

あなたは必要ありませんGettingModel(string vinText)方法。 を呼び出すことによってTask.Resultメインスレッドをブロックしています。

呼び出し.ResultUIスレッドであなたが経験しているものであるすべてをデッドロックするでしょう。つかいますContinueWithまたはasync voidawait

あなたはあなたを作ることができますEntry_TextChanged非同期とawaitWebリクエストはUIをブロックしないようにします。

あなたはそれを別のスレッドで実行して使うことさえできますContinueWith()操作が完了するのをmakeユーザーに待たせる必要がない場合。あなたがその経路に行くのなら、あなたが使うことを確認してくださいDevice.BeginInvookeOnMainThread()UIスレッドで実行する必要があるコードを実行します。

より良いコードは次のようになります。

private async void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
     var newText = e.NewTextValue;
     //once 3 keystroke is visible by 3
     if (newText.Length % 3 == 0)
     {
          //Call the web services
          var result = await GetModelStringForVIN(newText);
          if (string.IsNullOrEmpty(result) == false)
          {
               ModelVIN.Text = result;
          }    
     }
} 

private async Task<string> GetModelStringForVIN(string vinText)
{
      var deviceId = CrossDeviceInfo.Current.Model;
      deviceId = deviceId.Replace(" ", string.Empty);
      var requestMgr = new RequestManager(deviceId);

      var VinData = await requestMgr.getModelForVIN(vinText);

      return VinData?.Model;
 }

次のリンクは、概念をよりよく理解するのに役立ちます。

  1. Xamarin非同期サポートの概要
  2. Xamarinによる非同期操作


  • nullチェックは次のように置き換えることもできます。String.IsNullOrEmpty。一方、ModelVIN.Text初期化されていない場合はnullになります。書くだけじゃないのはなぜ?ModelVIN.Text = resultそれで? - Panagiotis Kanavos
  • @PanagiotisKanavos - キャッチをありがとう、コードを更新した。 - Rohit Vipin Mathews
  • @PanagiotisKanavos - ModelVINグローバルスコープ上の何かであり、ローカル変数ではありません、それは関数の実行前に値を持っているかもしれません。条件を満たしていない場合、OPは以前の値を保持したい場合があります。 - Rohit Vipin Mathews
  • 使用するときは注意してくださいContinueWithstackoverflow.com/questions/18965200/… - Krumelur

リンクされた質問


関連する質問

最近の質問