Timer in Portable Library

Timer in Portable Library

Update: We have fixed this in Visual Studio 2013. Portable libraries targeting Store (Windows 8.1) and .NET Framework 4.5.1 projects can now reference Timer.

This is unfortunate case of where our implementation details are leaking to the user. When you target just .NET 4.5 and Windows Store apps, we actually cause you to build against something different then when you target a down-level platform (.NET 4, SL 4/5, Phone 7.x). We try treat these two as the same, but limited changes underneath start to leak (such as Timer, and Reflection). We cover some of this here: http://channel9.msdn.com/Shows/Going+Deep/NET-45-David-Kean-and-Marcea-Trofin-Portable-Libraries.

We'll look at fixing this in a future version. Until then, you have a couple of workarounds:

1) Implement your own version of Timer using Task.Delay, here's a quick copy that we're using internally:

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) Downgrade your project to .NET 4.0 and Windows Store apps, which will give you access to Timer.

3) Create a new project targeting .NET 4.0 and Windows Store apps, and put the code that requires timer in that. Then reference that from the .NET 4.5 and Windows Store apps project.

As a side note, I've filed a work item for myself over on PclContrib site to add Timer support: http://pclcontrib.codeplex.com/workitem/12513.

Timer in portable class library

If you interested in implementing Timer with Tasks, you can try this code:

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

As already mentioned you can introduce dependency on some interface and ask user to give you particular timer implementation.

How to create an effecient portable timer in C++?

There's not an easy way to do what you're thinking. Luckily, there are easy ways to do what you want.

First: Using the functions time() and difftime() in a loop to determine how much time was elapsed That's a terrible idea. That will use 100% of one of your CPUs and thus slow your program to a crawl. If you want to wait a specific amount of time (a "tick" of 1/60 of a second, or 1/10 of a second), then just wait. Don't spin a thread.

header:

long long get_time();
long long get_freq();
void wait_for(long long nanoseconds);

cpp:

#ifdef _MSC_VER //windows compiler for windows machines
long long get_time() {
LARGE_INTEGER r;
QueryPerformanceCounter(r);
return r.QuadPart;
}
long long get_freq() {
LARGE_INTEGER r;
QueryPerformanceFrequency(r);
return r.QuadPart;
}
void wait_for(long long nanoseconds)
{
Sleep(nanoseconds / 1000000);
}
#endif
#ifdef __GNUC__ //linux compiler for linux machines
long long get_time() {
timespec r
clock_gettime(CLOCK_MONOTONIC, &r);
return long long(r.seconds)*1000000000 + r.nanoseconds;
}
long long get_freq() {
timespec r
clock_getres(CLOCK_MONOTONIC, &r);
return r.nanoseconds;
}
void wait_for(long long nanoseconds)
{
timespec r = {nanoseconds/1000000000, nanoseconds%1000000000};
nanosleep(&r, NULL);
}
#endif

None of this is perfect (especially since I don't code for linux), but this is the general concept whenever you have to deal with the OS (since it isn't in the standard and you cant use libraries). The Windows and GCC implementations can be in separate files if you like

timer_create and TimerQueueTimer functionality in portable library (like boost)

POCO has a multi-threaded Timer class that runs TimerTask(s). Basically you override a TimerTask's run() method with what you want to do when the timer expires. Multiple tasks can be added to the Timer object which spawns a thread to sequentially run all pending tasks. The tasks can be one-time or interval repeatable.

Not sure if it meets all of your needs but it is worth looking at.

Hexadecimal clock in Portable Class Library c#

You can use the converter method below to perform the conversion:

const int HexUnitsInDay = 16 * 16 * 16 * 16;
const int SecondsInDay = 24 * 60 * 60;

public static string ConvertToHexTime(TimeSpan tm)
{
int hexTime = Convert.ToInt32(tm.TotalSeconds * HexUnitsInDay / SecondsInDay);
return String.Format(".{0:X}", hexTime);
}

Usage example:

Console.WriteLine(ConvertToHexTime(DateTime.Now.TimeOfDay));

To update the screen on a regular basis, you can use a system timer-event-generation class.

In WPF you can use the System.Windows.Threading.DispatcherTimer class for that, e.g. a clock in c# wpf application

In Winforms you can use the System.Windows.Forms.Timer class for that, e.g. Run a Digital Clock on your WinForm

In both cases: set the update-interval to 1318 milliseconds (this roughly equals SecondsInDay / HexUnitsInDay).

Can I use System.Timers.Timer in an F# PCL library?

The System.Timers.Timer (and System.Threading.Timer) classes don't work in the main F# PCL profiles. Given that normal F# async is supported, you can easily work around this by writing your own "timer" type. For example, the following (while a bit ugly) should mimic the Timer class functionality reasonably well:

type PclTimer(interval, callback) = 
let mb = new MailboxProcessor<bool>(fun inbox ->
async {
let stop = ref false
while not !stop do
// Sleep for our interval time
do! Async.Sleep interval

// Timers raise on threadpool threads - mimic that behavior here
do! Async.SwitchToThreadPool()
callback()

// Check for our stop message
let! msg = inbox.TryReceive(1)
stop := defaultArg msg false
})

member __.Start() = mb.Start()
member __.Stop() = mb.Post true

Portable periodic timer for period around 100ms

As most straightforward way to achieve this is to use Sleep(100ms) in a cycle, all you need is a portable Sleep. For Linux it can be implemented as follows

void Sleep(unsigned long ulMilliseconds)
{
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = ulMilliseconds * 1000;
select(1, NULL, NULL, NULL, &timeout);
}


Related Topics



Leave a reply



Submit