Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ConcurrencyAbstractionLayerImpl.Windows.cs « Concurrency « Reactive « System.Reactive.PlatformServices « Rx.NET - github.com/mono/rx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1d5c0ae13fde7ffc297574fe786bd639cbbda3e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#if NO_THREAD && WINDOWS
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Threading;

namespace System.Reactive.Concurrency
{
    internal class /*Default*/ConcurrencyAbstractionLayerImpl : IConcurrencyAbstractionLayer
    {
        public IDisposable StartTimer(Action<object> action, object state, TimeSpan dueTime)
        {
            var res = global::Windows.System.Threading.ThreadPoolTimer.CreateTimer(
                tpt =>
                {
                    action(state);
                },
                Normalize(dueTime)
            );

            return Disposable.Create(res.Cancel);
        }

        public IDisposable StartPeriodicTimer(Action action, TimeSpan period)
        {
            //
            // The WinRT thread pool is based on the Win32 thread pool and cannot handle
            // sub-1ms resolution. When passing a lower period, we get single-shot
            // timer behavior instead. See MSDN documentation for CreatePeriodicTimer
            // for more information.
            //
            if (period < TimeSpan.FromMilliseconds(1))
                throw new ArgumentOutOfRangeException("period", Strings_PlatformServices.WINRT_NO_SUB1MS_TIMERS);

            var res = global::Windows.System.Threading.ThreadPoolTimer.CreatePeriodicTimer(
                tpt =>
                {
                    action();
                },
                period
            );

            return Disposable.Create(res.Cancel);
        }

        public IDisposable QueueUserWorkItem(Action<object> action, object state)
        {
            var res = global::Windows.System.Threading.ThreadPool.RunAsync(iaa =>
            {
                action(state);
            });

            return Disposable.Create(res.Cancel);
        }
        
        public void Sleep(TimeSpan timeout)
        {
            var e = new ManualResetEventSlim();

            global::Windows.System.Threading.ThreadPoolTimer.CreateTimer(
                tpt =>
                {
                    e.Set();
                },
                Normalize(timeout)
            );

            e.Wait();
        }

        public IStopwatch StartStopwatch()
        {
#if !NO_STOPWATCH
            return new StopwatchImpl();
#else
            return new DefaultStopwatch();
#endif
        }

        public bool SupportsLongRunning
        {
            get { return false; }
        }

        public void StartThread(Action<object> action, object state)
        {
            throw new NotSupportedException();
        }

        private TimeSpan Normalize(TimeSpan dueTime)
        {
            if (dueTime < TimeSpan.Zero)
                return TimeSpan.Zero;

            return dueTime;
        }
    }
}
#endif