1- using System ;
2- using System . Runtime . CompilerServices ;
3- using System . Threading ;
1+ using System . Threading ;
42using System . Threading . Tasks ;
53
64namespace GitHub . Unity
@@ -19,102 +17,15 @@ public static void SetUIThread()
1917
2018 public static bool InUIThread => InMainThread || Guard . InUnitTestRunner ;
2119
22- /// <summary>
23- /// Switch to the UI thread
24- /// Auto-disables switching when running in unit test mode
25- /// </summary>
26- /// <returns></returns>
27- public static IAwaitable SwitchToMainThreadAsync ( )
20+ public static TaskScheduler GetUIScheduler ( SynchronizationContext synchronizationContext )
2821 {
29- return Guard . InUnitTestRunner ?
30- new AwaitableWrapper ( ) :
31- new AwaitableWrapper ( MainThreadScheduler ) ;
22+ // quickly swap out the sync context so we can leverage FromCurrentSynchronizationContext for our ui scheduler
23+ var currentSyncContext = SynchronizationContext . Current ;
24+ SynchronizationContext . SetSynchronizationContext ( synchronizationContext ) ;
25+ var ret = TaskScheduler . FromCurrentSynchronizationContext ( ) ;
26+ if ( currentSyncContext != null )
27+ SynchronizationContext . SetSynchronizationContext ( currentSyncContext ) ;
28+ return ret ;
3229 }
33-
34-
35- /// <summary>
36- /// Switch to a thread pool background thread if the current thread isn't one, otherwise does nothing
37- /// Auto-disables switching when running in unit test mode
38- /// </summary>
39- /// <param name="scheduler"></param>
40- /// <returns></returns>
41- public static IAwaitable SwitchToThreadAsync ( TaskScheduler scheduler = null )
42- {
43- return Guard . InUnitTestRunner ?
44- new AwaitableWrapper ( ) :
45- new AwaitableWrapper ( scheduler ?? TaskManager . Instance . ConcurrentScheduler ) ;
46- }
47-
48- class AwaitableWrapper : IAwaitable
49- {
50- Func < IAwaiter > getAwaiter ;
51-
52- public AwaitableWrapper ( )
53- {
54- getAwaiter = ( ) => new AwaiterWrapper ( ) ;
55- }
56-
57- public AwaitableWrapper ( TaskScheduler scheduler )
58- {
59- getAwaiter = ( ) => new AwaiterWrapper ( new TaskSchedulerAwaiter ( scheduler ) ) ;
60- }
61-
62- public IAwaiter GetAwaiter ( ) => getAwaiter ( ) ;
63- }
64-
65- class AwaiterWrapper : IAwaiter
66- {
67- Func < bool > isCompleted ;
68- Action < Action > onCompleted ;
69- Action getResult ;
70-
71- public AwaiterWrapper ( )
72- {
73- isCompleted = ( ) => true ;
74- onCompleted = c => c ( ) ;
75- getResult = ( ) => { } ;
76- }
77-
78- public AwaiterWrapper ( TaskSchedulerAwaiter awaiter )
79- {
80- isCompleted = ( ) => awaiter . IsCompleted ;
81- onCompleted = c => awaiter . OnCompleted ( c ) ;
82- getResult = ( ) => awaiter . GetResult ( ) ;
83- }
84-
85- public bool IsCompleted => isCompleted ( ) ;
86-
87- public void OnCompleted ( Action continuation ) => onCompleted ( continuation ) ;
88-
89- public void GetResult ( ) => getResult ( ) ;
90- }
91-
92- public struct TaskSchedulerAwaiter : INotifyCompletion
93- {
94- private readonly TaskScheduler scheduler ;
95-
96- public bool IsCompleted
97- {
98- get
99- {
100- return ( this . scheduler == TaskManager . Instance . UIScheduler && InUIThread ) || ( this . scheduler != TaskManager . Instance . UIScheduler && ! InUIThread ) ;
101- }
102- }
103-
104- public TaskSchedulerAwaiter ( TaskScheduler scheduler )
105- {
106- this . scheduler = scheduler ;
107- }
108-
109- public void OnCompleted ( Action action )
110- {
111- Task . Factory . StartNew ( action , TaskManager . Instance . Token , TaskCreationOptions . None , this . scheduler ) ;
112- }
113-
114- public void GetResult ( )
115- {
116- }
117- }
118-
11930 }
120- }
31+ }
0 commit comments