2017-12-20 10 views
0

非常に奇妙なシナリオ...誰かが助けてくれるかもしれません。この上に私の頭を壊す。OnPropertyChanged()がトリガーされてから10秒後にXamarin UIが更新されます

private string _myText = "Hello"; 
public string MyText 
{ 
    get { return _myText; } 

    set 
    { 
     _myText = value; 
     OnPropertyChanged(); 
     //OnPropertyChanged("IsSearching"); 
    } 
} 

私は、このメソッドを実行したときに何が起こっているかをデバッグするXAML Xamarinビューでラベルに自分のMyTextをバインドさ。

ボタンは、テキストが更新される素晴らしいクリックされたが、それだけで、3に更新されますすることになっている10〜15秒のような第二の時間に更新されますので、
private async void Edit_Survey_Button_OnClicked(object sender, EventArgs e) 
{ 
    MyText = "Text Before Long Method"; 
    Stopwatch s = new Stopwatch(); 
    await Task.Run(() => 
    { 
     s.Start(); 
     Task.Delay(3000).Wait(); 
     MyText = "Text after long method" + s.ElapsedMilliseconds.ToString(); 
    }); 
} 

!私はなぜこれを実行するかについて非常に多くのオプションを試したのですが、MyTextが別のスレッドに設定されている可能性があります。

遅延の代わりにデータのダウンロードが行われ、データのダウンロード後にいくつかのUI要素が初期状態から変更されているため、このテストを行っています。今、私はそれをどうやって行うのかについて疑いがあり、うまくいけば、他の人も同様の状況に遭遇していることを願っています。

________Update 1 SushiHangoverにより示唆されるように

private void Edit_Survey_Button_OnClicked(object sender, EventArgs e) 
    { 
     IsSearching = "Method Start Edit"; 

     Task.Run(async() => 
     { 
      await Task.Delay(3000); 

      Device.BeginInvokeOnMainThread(() => { IsSearching = "Yeeeeehuuuuuuu!"; }); 


     }); 
    } 

助けにはなりませんでした。

+1

あなたは '.Wait()'を使って*を同期的にブロックしていますが、代わりに 'await Task.Delay(3000);'を使用します。そしてあなたの 'TaskRun'で、' MyText'割り当てを 'Device.BeginInvokeOnMainThread'にラップします。 – SushiHangover

+0

不幸にもこれはうまくいきません –

+0

しかし、それは完全に意味があります、私はあなたが言及したものをどのように実装したかについての更新を挿入しました。まだ動作しません。 lableは20秒で更新されます... –

答えて

1

はこれを試してみてください:

private async void Edit_Survey_Button_OnClicked(object sender, EventArgs e) 
{ 
    MyText = "Text Before Long Method"; 
    Stopwatch s = new Stopwatch(); 
    s.Start(); 
    await Task.Delay(3000); 
    s.Stop(); 
    MyText = "Text after long method" + s.ElapsedMilliseconds.ToString(); 
} 
+0

ラベルは更新されますが、20秒後にしか更新されません。作業が完了した後に遅延を待たせるために、私は完全に同意します。MyTextを変更してもUIは更新されませんimmidiatlyと私は正確になぜ正確に考えていない。 –

+0

私はこれを新しい空のアプリケーションで試してみることをお勧めします。他には何も起こっていません。 – mm8

+0

Xamarinのコンテキストではなく単純なコンソールアプリケーションのコンテキストで試してみますそれは完璧に実行されます。値はコンソールで更新されます。 Xamarinの値が20-25秒で更新される場合 –

1

私は、iOSエミュレータとAndroidの両方でこのコードを実行し、それが正常に動作します:

namespace Yuri1 
{ 
public partial class Yuri1Page : ContentPage 
{ 
    async void Handle_Clicked(object sender, System.EventArgs e) 
    { 
     Stopwatch s = new Stopwatch(); 
     await Task.Run(() => 
     { 
      s.Start(); 
      Task.Delay(3000).Wait(); 

     }); 

     MyEntry.Text="Text after long method: " + s.ElapsedMilliseconds.ToString(); 

    } 


     //MyText.Text = "Text after long method" + s.ElapsedMilliseconds.ToString();  } 

    public Yuri1Page() 
     { 
      InitializeComponent(); 
     } 


} 


} 
+0

私はBeginInvokeOnMainThreadをラップして上記の例にも同意します – humpynzl

0

この議論に参加した皆のための非常にgreatfull。だから、これを理解する数多くの試みの後、最も適切な解決策はこのように見える。遅延タスクが完了した後にUIを更新するために必要な遅延が問題なく機能しているようです。この例では、スレッドIDをデバッグし、両方のタイプのバインディングx参照とデータバインディングも試みました。

List<string> threads = new List<string>(); 

    private BindableProperty IsSearchingProperty = 
     BindableProperty.Create("IsSearching", typeof(string), typeof(MainPage), "Hello"); 

    public string IsSearching 
    { 
     get { return (string)GetValue(IsSearchingProperty); } 
     set { SetValue(IsSearchingProperty, value); } 
    } 

    public MainPage() 
    { 
     BindingContext = this; 
     InitializeComponent(); 
     threads.Add(GetThreadId() + " in constructor"); 
    } 

    private string GetThreadId() 
    { 
     return Thread.CurrentThread.ManagedThreadId.ToString(); 
    } 

    private async void Button_OnClicked(object sender, EventArgs e) 
    { 
     threads.Add(GetThreadId() + " in method"); 

     IsSearching = "Method Start Edit"; 
     MyRef.Text = "Reference Text Start"; 
     Stopwatch s = new Stopwatch(); 

     await Task.Run(() => 
     { 
      threads.Add(GetThreadId() + " in task"); 
      s.Start(); 
      Task.Delay(3000).Wait(); 


      Device.BeginInvokeOnMainThread(() => 
      { 
       IsSearching = "Yeeeeehuuuuuuu!"; 
       MyRef.Text = "Reference Text End" + s.ElapsedMilliseconds.ToString(); ; 
       threads.Add(GetThreadId() + " in task in device begin invoke"); 
      }); 
     }); 

     threads.Add(GetThreadId() + " after task"); 
     DisplayAlert("My Threads", DiplayThreadInfo(), "Cancel"); 
     threads = null; 

    } 

    private string DiplayThreadInfo() 
    { 

     string threadsInfo = null; 

     foreach (var thread in threads) 
     { 
      threadsInfo ="/"+ threadsInfo + thread + "/"+ Environment.NewLine; 
     } 

     return threadsInfo; 
    } 
} 

スレッドのデバッグ後、UIの更新がUIスレッドで実行されることがわかります。もしこれが行われなければ、問題が起こり始めるのは不可欠です。全体的にこのsemmsは仕事をする。みんなありがとう。

+0

しかし、興味深いのは、問題が再生されたのと同じ方法でIsVisibleを更新しようとする場合です。 –

関連する問題