/
TaskExtensions.cs
129 lines (112 loc) · 4.16 KB
/
TaskExtensions.cs
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNet.Identity
{
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
internal static class TaskExtensions
{
public static CultureAwaiter<T> WithCurrentCulture<T>(this Task<T> task)
{
return new CultureAwaiter<T>(task);
}
public static CultureAwaiter WithCurrentCulture(this Task task)
{
return new CultureAwaiter(task);
}
public struct CultureAwaiter<T> : ICriticalNotifyCompletion
{
private readonly Task<T> _task;
public CultureAwaiter(Task<T> task)
{
_task = task;
}
public CultureAwaiter<T> GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public T GetResult()
{
return _task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
public struct CultureAwaiter : ICriticalNotifyCompletion
{
private readonly Task _task;
public CultureAwaiter(Task task)
{
_task = task;
}
public CultureAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public void GetResult()
{
_task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
}
}