Den*_*öer 3 timer xamarin xamarin.forms
我正在开发一款聊天应用.在加载聊天消息并且消息可见5秒后,我想向服务器发送读取确认.这是我到目前为止所提出的:
public async void RefreshLocalData()
{
// some async code to load the messages
if (_selectedChat.countNewMessages > 0)
{
Device.StartTimer(TimeSpan.FromSeconds(5), SendReadConfirmation);
}
}
Run Code Online (Sandbox Code Playgroud)
当RefreshLocalData()被叫时,我知道用户选择了另一个聊天,或者当前聊天中有新消息.因此,当RefreshLocalData()被调用时,我必须取消当前的计时器以启动一个新计时器.
另一种情况,当我导航到另一个时,我必须取消计时器Page.这没有问题,因为ViewModel当发生这种情况时整个都被处理掉了.
使用上面的代码,如果RefreshLocalData()再次调用if 但是TimeSpan5秒的声明尚未结束,则该方法仍在执行.
有没有办法取消计时器(如果RefreshLocalData()再次调用)?
我在Xamarin论坛中找到了这个答案:https://forums.xamarin.com/discussion/comment/149877/#Comment_149877
我已经改变了一点以满足我的需求,这个解决方案正在起作用:
public class StoppableTimer
{
private readonly TimeSpan timespan;
private readonly Action callback;
private CancellationTokenSource cancellation;
public StoppableTimer(TimeSpan timespan, Action callback)
{
this.timespan = timespan;
this.callback = callback;
this.cancellation = new CancellationTokenSource();
}
public void Start()
{
CancellationTokenSource cts = this.cancellation; // safe copy
Device.StartTimer(this.timespan,
() => {
if (cts.IsCancellationRequested) return false;
this.callback.Invoke();
return false; // or true for periodic behavior
});
}
public void Stop()
{
Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
}
public void Dispose()
{
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我在RefreshLocalData()方法中使用它的方式:
private StoppableTimer stoppableTimer;
public async void RefreshLocalData()
{
if (stoppableTimer != null)
{
stoppableTimer.Stop();
}
// some async code to load the messages
if (_selectedChat.countNewMessages > 0)
{
if (stoppableTimer == null)
{
stoppableTimer = new StoppableTimer(TimeSpan.FromSeconds(5), SendReadConfirmation);
stoppableTimer.Start();
}
else
{
stoppableTimer.Start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3717 次 |
| 最近记录: |