web-dev-qa-db-ja.com

Xミリ秒後に開始するアクションをトリガーする

Xamarinフォームモバイルアプリを開発しています。これには、SearchBar、ListView、およびMapコントロールを含むページがあります。リストビューには、地図上にピンとして反映されている住所のリストが含まれています。

ユーザーがSearchBarに入力すると、ListViewが自動的に更新されます(ViewModelバインディングによって)。リストのデータソースをフィルターするViewModelメソッドは次のようになります...

void FilterList()
{
    listDataSource = new ObservableCollection<location>(
        locationData.Where(l => l.Address.Contains(searchBar.Text))
    );

    // ***** Now, update the map pins using the data in listDataSource
}

ListViewがフィルターされているときにマップを更新したいのですが、1秒に複数回発生する可能性があるため、すべてのキーを押す必要はありません。基本的に、マップが更新される前に、各FilterListイベントに「ローリングポーズ」が必要です。疑似コードで...

    // ***** Now, update the map pins using the data in listDataSource
    if (a previously-requested map update is pending)
    {
        // Cancel the pending map update request
    }

    // Request a new map update in 1000ms using [listDataSource]

Stopwatchクラスを使用してこれを行うことは可能です。これは、ポータブルクラスライブラリで利用できますが、-Tasksを使用してこれを実行するためのよりクリーンで優れた方法があると思います。

誰かが「より賢い」-PCL互換これを行う方法を提案できますか?

17
bosco

単純な遅延の問題は、遅延の期限が切れたときにキューに入れられる一連のイベントを取得できることです。遅延の実行中に発生したイベントを破棄するロジックを追加できます。より高いレベルでロジックを宣言する場合は、 Reactive Extensions を使用できます。

1
Edward Brey

あなたが試すことができます :

await Task.Delay(2000);
18
Rui Marinho

あなたが言ったように、これはTasksと非同期プログラミングを使用して非常にクリーンな方法で達成できます。

あなたはそれについて読みたくなるでしょう: http://msdn.Microsoft.com/en-us/library/hh191443.aspx

次に例を示します。

public async Task DelayActionAsync(int delay, Action action) 
{
    await Task.Delay(delay);

    action();
}
12
dan

これが私がやったことであり、それは私のXamarin Formアプリで動作します。

    public string Search
    {
        get { return _search; }
        set
        {
            if (_search == value)
                return;

            _search = value;
            triggerSearch = false;
            Task.Run(async () =>
            {
                string searchText = _search;
                await Task.Delay(2000);
                if (_search == searchText)
                {
                    await ActionToFilter();
                }
            });
        }
    }

この「検索」プロパティを入力フィールドにバインドしました。ユーザーが何かをフィルタリングするときはいつでも、コードは1秒間待機してから、新しいテキストフィールドを1秒前のフィールドと比較します。文字列が等しいと仮定すると、ユーザーがテキストの入力を停止し、コードをトリガーしてフィルターできるようになります。

10
HarshitGindra

最新のxamarinバージョンでの作業。

ボタンクリック時のもう1つの優れた方法は、

    public async void OnButtonClickHandler(Object sender, EventArgs e)
{
    try
    {
        //ShowProgresBar("Loading...");

        await Task.Run(() =>
        {
            Task.Delay(2000); //wait for two milli seconds

            //TODO Your Business logic goes here
            //HideProgressBar();

        });

        await DisplayAlert("Title", "Delayed for two seconds", "Okay");

    }
    catch (Exception ex)
    {

    }
}

asyncおよびawaitキーは重要です。マルチスレッド環境で作業しているとしましょう。

0
Zumry Mohamed