Xamarin 中的计时器不遵守您设置的时间
Timer in Xamarin doesn't honor the time you set
我正在开发 Xamarin 应用程序。其中一项要求是在一定时间后注销用户。我设置了一个计时器,每 30 分钟 运行s 告诉用户他的会话已过期,并让他选择继续他的会话或注销。如果他决定继续他的会话,计时器将继续每 30 分钟 运行,但如果他决定结束他的会话,计时器将停止。
Xamarin 中的计时器不遵守您在 StartTimer 上设置的时间,因为它 运行s 甚至在 30 分钟之前。
App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new LoginPage());
}
LoginPage.xaml.cs
public LoginPage()
{
InitializeComponent();
CheckUserLoginStatus();
}
public async void CheckUserLoginStatus()
{
var msalService = new MsalAuthService();
if (await msalService.SignInAsync())
{
Settings.UserLastLogin = DateTime.Now;
App.Current.MainPage = new Master();
}
}
MsalAuthService.cs
public async Task<bool> SignInAsync()
{
try
{
// login logic here
//after successfull login start timer
Device.StartTimer(new TimeSpan(0, 30, 0), () =>
{
// do something every 30 minutes
Device.BeginInvokeOnMainThread(async () =>
{
// interact with UI elements
await AutoLogout();
});
var accessToken = ApplicationPropertyProvider.GetProperty<string>(Commons.AUTH_TOKEN);
return !string.IsNullOrEmpty(accessToken);
});
Application.Current.Properties["USERLOGINDATE"] = DateTime.Now;
return !string.IsNullOrEmpty(accessToken);
}
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return false;
}
}
可以在没有计时器的情况下定期与用户交互:
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PeriodicInteractPage : ContentPage
{
public PeriodicInteractPage()
{
InitializeComponent();
StartPeriodicTask(5, GetUserConfirmation, Done);
}
delegate Task<bool> TaskBoolDeleg();
delegate Task TaskDeleg();
private void StartPeriodicTask(float seconds, TaskBoolDeleg periodicTask, TaskDeleg doneTask)
{
// On MainThread, so can interact with user.
// "async" + "await Delay" ensures UI is not blocked until time is up.
Device.BeginInvokeOnMainThread(async () =>
{
bool alive = true;
while (alive)
{
await Task.Delay((int)(1000 * seconds));
alive = await periodicTask();
}
await doneTask();
});
}
private async Task<bool> GetUserConfirmation()
{
// Block UI until user responds.
bool answer = await DisplayAlert("", "Are you still there?", "Yes", "No");
Debug.WriteLine($"--- Still there: {answer} ---");
return answer;
}
private async Task Done()
{
Debug.WriteLine($"--- DONE ---");
await DisplayAlert("", "Logout", "OK");
}
}
}
StartPeriodicTask(5, GetUserConfirmation, Done);
将在 5 秒后调用 GetUserConfirmation
。根据需要增加。
如果用户回答“是”,则时间延迟再次开始。
如果用户回答“否”,则循环退出,Done
运行。
CREDIT:大致基于 中的“无定时器”方法。
我正在开发 Xamarin 应用程序。其中一项要求是在一定时间后注销用户。我设置了一个计时器,每 30 分钟 运行s 告诉用户他的会话已过期,并让他选择继续他的会话或注销。如果他决定继续他的会话,计时器将继续每 30 分钟 运行,但如果他决定结束他的会话,计时器将停止。
Xamarin 中的计时器不遵守您在 StartTimer 上设置的时间,因为它 运行s 甚至在 30 分钟之前。
App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new LoginPage());
}
LoginPage.xaml.cs
public LoginPage()
{
InitializeComponent();
CheckUserLoginStatus();
}
public async void CheckUserLoginStatus()
{
var msalService = new MsalAuthService();
if (await msalService.SignInAsync())
{
Settings.UserLastLogin = DateTime.Now;
App.Current.MainPage = new Master();
}
}
MsalAuthService.cs
public async Task<bool> SignInAsync()
{
try
{
// login logic here
//after successfull login start timer
Device.StartTimer(new TimeSpan(0, 30, 0), () =>
{
// do something every 30 minutes
Device.BeginInvokeOnMainThread(async () =>
{
// interact with UI elements
await AutoLogout();
});
var accessToken = ApplicationPropertyProvider.GetProperty<string>(Commons.AUTH_TOKEN);
return !string.IsNullOrEmpty(accessToken);
});
Application.Current.Properties["USERLOGINDATE"] = DateTime.Now;
return !string.IsNullOrEmpty(accessToken);
}
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return false;
}
}
可以在没有计时器的情况下定期与用户交互:
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PeriodicInteractPage : ContentPage
{
public PeriodicInteractPage()
{
InitializeComponent();
StartPeriodicTask(5, GetUserConfirmation, Done);
}
delegate Task<bool> TaskBoolDeleg();
delegate Task TaskDeleg();
private void StartPeriodicTask(float seconds, TaskBoolDeleg periodicTask, TaskDeleg doneTask)
{
// On MainThread, so can interact with user.
// "async" + "await Delay" ensures UI is not blocked until time is up.
Device.BeginInvokeOnMainThread(async () =>
{
bool alive = true;
while (alive)
{
await Task.Delay((int)(1000 * seconds));
alive = await periodicTask();
}
await doneTask();
});
}
private async Task<bool> GetUserConfirmation()
{
// Block UI until user responds.
bool answer = await DisplayAlert("", "Are you still there?", "Yes", "No");
Debug.WriteLine($"--- Still there: {answer} ---");
return answer;
}
private async Task Done()
{
Debug.WriteLine($"--- DONE ---");
await DisplayAlert("", "Logout", "OK");
}
}
}
StartPeriodicTask(5, GetUserConfirmation, Done);
将在 5 秒后调用 GetUserConfirmation
。根据需要增加。
如果用户回答“是”,则时间延迟再次开始。
如果用户回答“否”,则循环退出,Done
运行。
CREDIT:大致基于