Boa*_*ler 33 c# timer portable-class-library microsoft-metro
我在便携式库/ Windows Store中找不到计时器.(定位.net 4.5和Windows Store又称Metro)
有没有人知道如何创建某种计时事件?
我需要一些秒表,所以这应该每秒刷新一次
Dav*_*ean 44
更新:我们已在Visual Studio 2013中修复此问题.针对Store(Windows 8.1)和.NET Framework 4.5.1项目的可移植库现在可以引用Timer.
这是我们的实施细节泄露给用户的不幸情况.当您只针对.NET 4.5和Windows应用商店应用时,我们实际上会让您构建针对不同的东西,然后定位到低级平台(.NET 4,SL 4/5,Phone 7.x).我们尝试将这两者视为相同,但在下面开始泄漏的有限变化(例如Timer和Reflection).我们在这里介绍其中一些内容:http://channel9.msdn.com/Shows/Going+Deep/NET-45-David-Kean-and-Marcea-Trofin-Portable-Libraries.
我们将在未来版本中考虑修复此问题.在那之前,您有几个解决方法:
1)使用Task.Delay实现自己的Timer版本,这是我们在内部使用的快速副本:
internal delegate void TimerCallback(object state);
internal sealed class Timer : CancellationTokenSource, IDisposable
{
internal Timer(TimerCallback callback, object state, int dueTime, int period)
{
Contract.Assert(period == -1, "This stub implementation only supports dueTime.");
Task.Delay(dueTime, Token).ContinueWith((t, s) =>
{
var tuple = (Tuple<TimerCallback, object>)s;
tuple.Item1(tuple.Item2);
}, Tuple.Create(callback, state), CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default);
}
public new void Dispose() { base.Cancel(); }
}
Run Code Online (Sandbox Code Playgroud)
2)将您的项目降级到.NET 4.0和Windows应用商店应用程序,这将使您可以访问Timer.
3)创建一个面向.NET 4.0和Windows应用商店应用的新项目,并将需要定时器的代码放入其中.然后从.NET 4.5和Windows应用商店应用项目中引用它.
作为旁注,我已经在PclContrib网站上为自己提交了一个工作项,以添加Timer支持:http://pclcontrib.codeplex.com/workitem/12513 .
根据David Kean的建议#3,这是我的hacky Timer适配器 - 将它放在一个针对.net 4.0的PCL库中,并从4.5引用它:
public class PCLTimer
{
private Timer _timer;
private Action _action;
public PCLTimer(Action action, TimeSpan dueTime, TimeSpan period)
{
_action = action;
_timer = new Timer(PCLTimerCallback, null, dueTime, period);
}
private void PCLTimerCallback(object state)
{
_action.Invoke();
}
public bool Change(TimeSpan dueTime, TimeSpan period)
{
return _timer.Change(dueTime, period);
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它,您可以从4.5 PCL库中执行此操作:
private void TimeEvent()
{
//place your timer callback code here
}
public void SetupTimer()
{
//set up timer to run every second
PCLTimer _pageTimer = new PCLTimer(new Action(TimeEvent), TimeSpan.FromMilliseconds(-1), TimeSpan.FromSeconds(1));
//timer starts one second from now
_pageTimer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}
Run Code Online (Sandbox Code Playgroud)
执行David Kean提出的建议#1期间:
public delegate void TimerCallback(object state);
public sealed class Timer : CancellationTokenSource, IDisposable
{
public Timer(TimerCallback callback, object state, int dueTime, int period)
{
Task.Delay(dueTime, Token).ContinueWith(async (t, s) =>
{
var tuple = (Tuple<TimerCallback, object>) s;
while (true)
{
if (IsCancellationRequested)
break;
Task.Run(() => tuple.Item1(tuple.Item2));
await Task.Delay(period);
}
}, Tuple.Create(callback, state), CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default);
}
public new void Dispose() { base.Cancel(); }
}
Run Code Online (Sandbox Code Playgroud)