定时器便携式图书馆(Timer in Portable Library)

2019-06-18 06:44发布

我无法找到可移植库/ Windows应用商店的一个计时器。 (靶向.NET 4.5和Windows商店又名地铁)

有没有任何有关于如何创建某种定时事件的想法?

我需要一个秒表somekind的,所以这应该REFRESHN一次一秒左右

Answer 1:

更新:我们已经在Visual Studio中修复了这个2013年便携式图书馆针对商店(Windows 8.1中)和.NET Framework 4.5.1项目现在可以参考定时器。

这是我们实现细节泄露给用户的不幸情况。 当你的目标只是.NET 4.5和Windows Store应用程序,我们实际上会导致您打造针对不同的东西,然后当你瞄准一个低级别平台(.NET 4,SL 4/5,电话7.x版)。 我们试图将这两个一样的,但有限的变化下开始泄漏(如定时器,和反射)。 我们介绍一些这样的位置: http://channel9.msdn.com/Shows/Going+Deep/NET-45-David-Kean-and-Marcea-Trofin-Portable-Libraries 。

我们将着眼于在未来版本中修复这个。 在那之前,你有几个解决方法:

1)用C语言实现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(); }
}

2)降级您的项目以.NET 4.0和Windows Store应用程序,这将让您使用定时器。

3)创建一个新的项目针对.NET 4.0和Windows应用商店的应用程序,并把需要定时器的代码。 然后引用从.NET 4.5和Windows Store应用程序项目。

作为一个方面说明,我已经申请了自己的工作项目在上PclContrib网站添加定时器支持: http://pclcontrib.codeplex.com/workitem/12513 。



Answer 2:

从大卫·基恩以下建议#3,这是我的哈克定时器适配器 - 把这个面向.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);
        }
    }

然后使用它,您可以从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));

    }


Answer 3:

建议#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(); }
}


Answer 4:

我通过包括一个新的参数,给你回调,如果周期小于回调运行时,其呼叫排队改善伊万Leonenko答案。 ,取而代之的是一个动作遗留TimerCallback。 最后,使用我们取消令牌在最后延迟,并用ConfigureAwait增加并发,作为回调可以在任何线程上执行。

internal sealed class Timer : CancellationTokenSource
{
    internal Timer(Action<object> callback, object state, int millisecondsDueTime, int millisecondsPeriod, bool waitForCallbackBeforeNextPeriod = false)
    {
        //Contract.Assert(period == -1, "This stub implementation only supports dueTime.");

        Task.Delay(millisecondsDueTime, Token).ContinueWith(async (t, s) =>
        {
            var tuple = (Tuple<Action<object>, object>) s;

            while (!IsCancellationRequested)
            {
                if (waitForCallbackBeforeNextPeriod)
                    tuple.Item1(tuple.Item2);
                else
                    Task.Run(() => tuple.Item1(tuple.Item2));

                await Task.Delay(millisecondsPeriod, Token).ConfigureAwait(false);
            }

        }, Tuple.Create(callback, state), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
    }

    protected override void Dispose(bool disposing)
    {
        if(disposing)
            Cancel();

        base.Dispose(disposing);
    }
}


Answer 5:

您可以创建使用PCL库中的计时器接口,然后创建使用W8S计时器第二W8S库接口的实现。

然后你可以使用依赖注入到W8S库注入到PCL类。



Answer 6:

我结束了Observable.Timer从被动扩展(Rx)的。 rx下已经包含在项目中,这样的附加参考不是一个问题。

这里是触发每一秒的定时器:

IDisposable timer = Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
    .Subscribe(_ => /* your useful code here */);

// unsubscribe/stop when timer is no longer needed
timer.Dispose();

System.Reactive.Linq.Observable类是在PCL友好Rx-Linq NuGet包。



文章来源: Timer in Portable Library