私はチャットアプリを開発中です。チャットのメッセージが読み込まれ、メッセージが5秒間表示された後、私はサーバーに読み取り確認を送信したいと思います。これは私がこれまでに作ってみたものです:RefreshLocalData()
が呼び出されるとタイマーが終了する前にキャンセルする方法
public async void RefreshLocalData()
{
// some async code to load the messages
if (_selectedChat.countNewMessages > 0)
{
Device.StartTimer(TimeSpan.FromSeconds(5), SendReadConfirmation);
}
}
は、私は別のチャットのいずれかが、ユーザが選択したか、新しいメッセージが現在のチャットのために入って来たことを知っています。だからRefreshLocalData()
が呼び出されたら、私は現在のタイマーをキャンセルして新しいタイマーを開始する必要があります。
別の状況では、もう1つのPage
に移動するとタイマーをキャンセルする必要があります。このとき、ViewModel
全体が処理されるため、問題ありません。
上記のコードでは、RefreshLocalData()
が再度呼び出されたが、TimeSpan
の5秒がまだ終了していない場合、このメソッドはまだ実行されています。
タイマーをキャンセルする方法がありますか(RefreshLocalData()
が再度呼び出された場合)?あなたの目的のためにその後
public class MySystemDeviceTimer
{
private readonly TimeSpan timespan;
private readonly Action callback;
private CancellationTokenSource cancellation;
public bool running { get; private set; }
public MySystemDeviceTimer(TimeSpan timespan, Action callback)
{
this.timespan = timespan;
this.callback = callback;
this.cancellation = new CancellationTokenSource();
}
public void Start()
{
running = true;
start(true);
}
private void start(bool continuous)
{
CancellationTokenSource cts = this.cancellation; // safe copy
Device.StartTimer(this.timespan,
() =>
{
if (cts.IsCancellationRequested)
{
running = false;
return false;
}
this.callback.Invoke();
return continuous;
});
}
public void FireOnce()
{
running = true;
start(false);
running = false;
}
public void Stop()
{
Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
}
}
:
これはない 'Xamarin.Forms.Device.StartTimer()'とフォームプロジェクトで使用すべきではないため、 'System.Threading.Timer'を使用するためです。 'Device.StartTimer()'を使うだけです。 – BrewMate
@ BrewMate Formsプロジェクトでこれを使用しないのはなぜですか?私は 'System.Threading.Timer'を使用していません。このコードでは全く問題なく動作しています –