##// END OF EJS Templates
Added support for 'await' operator to promises
cin -
r151:ec91a6dfa5b3 v2
parent child
Show More
@@ -0,0 +1,28
1 using System;
2 using System.Runtime.CompilerServices;
3
4 namespace Implab {
5 public struct PromiseAwaiter : INotifyCompletion {
6 readonly IPromise m_promise;
7
8 public PromiseAwaiter(IPromise promise) {
9 m_promise = promise;
10 }
11
12 public void OnCompleted (Action continuation) {
13 if (m_promise != null)
14 m_promise.On(continuation, PromiseEventType.All);
15 }
16
17 public void GetResult() {
18 m_promise.Join();
19 }
20
21 public bool IsCompleted {
22 get {
23 return m_promise.IsResolved;
24 }
25 }
26 }
27 }
28
@@ -0,0 +1,28
1 using System;
2 using System.Runtime.CompilerServices;
3
4 namespace Implab {
5 public struct PromiseAwaiter<T> : INotifyCompletion {
6 readonly IPromise<T> m_promise;
7
8 public PromiseAwaiter(IPromise<T> promise) {
9 m_promise = promise;
10 }
11
12 public void OnCompleted (Action continuation) {
13 if (m_promise != null)
14 m_promise.On(continuation, PromiseEventType.All);
15 }
16
17 public T GetResult() {
18 return m_promise.Join();
19 }
20
21 public bool IsCompleted {
22 get {
23 return m_promise.IsResolved;
24 }
25 }
26 }
27 }
28
@@ -12,6 +12,7
12 12 <AssemblyName>Implab.Fx</AssemblyName>
13 13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14 14 <FileAlignment>512</FileAlignment>
15 <ReleaseVersion>0.2</ReleaseVersion>
15 16 </PropertyGroup>
16 17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 18 <DebugSymbols>true</DebugSymbols>
@@ -845,6 +845,19 namespace Implab.Test {
845 845 Console.WriteLine(m);
846 846 }
847 847 }
848
849 #if NET_4_5
850
851 [TestMethod]
852 public async void TaskInteropTest() {
853 var promise = new Promise<int>();
854 promise.Resolve(10);
855 var res = await promise;
856
857 Assert.AreEqual(10, res);
858 }
859
860 #endif
848 861 }
849 862 }
850 863
@@ -10,6 +10,7
10 10 <RootNamespace>Implab.Test</RootNamespace>
11 11 <AssemblyName>Implab.Test</AssemblyName>
12 12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
13 14 </PropertyGroup>
14 15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 16 <DebugSymbols>true</DebugSymbols>
@@ -79,7 +79,6 Global
79 79 {2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
80 80 EndGlobalSection
81 81 GlobalSection(MonoDevelopProperties) = preSolution
82 StartupItem = MonoPlay\MonoPlay.csproj
83 82 Policies = $0
84 83 $0.CSharpFormattingPolicy = $1
85 84 $1.IndentSwitchBody = True
@@ -279,6 +278,8 Global
279 278 $34.NamingStyle = PascalCase
280 279 $34.IncludeInstanceMembers = True
281 280 $34.IncludeStaticEntities = True
281 version = 0.2
282 StartupItem = MonoPlay\MonoPlay.csproj
282 283 EndGlobalSection
283 284 GlobalSection(TestCaseManagementSettings) = postSolution
284 285 CategoryFile = Implab.vsmdi
@@ -27,46 +27,6 namespace Implab {
27 27 Exception Error { get; }
28 28
29 29 /// <summary>
30 /// Creates a new promise dependend on the current one and resolved on
31 /// executing the specified handlers.
32 /// </summary>
33 /// <param name="success">The handler called on the successful promise completion.</param>
34 /// <param name="error">The handler is called if an error while completing the promise occurred.</param>
35 /// <param name="cancel">The handler is called in case of promise cancellation.</param>
36 /// <returns>The newly created dependant promise.</returns>
37 /// <remarks>
38 /// <para>
39 /// If the success handler is specified the dependend promise will be resolved after the handler is
40 /// executed and the dependent promise will be linked to the current one, i.e. the cancellation
41 /// of the dependent property will lead to the cancellation of the current promise. If the
42 /// success handler isn't specified the dependent promise will not be linked to and
43 /// will not be resolved after the successfull resolution of the current one.
44 /// </para>
45 /// <para>
46 /// When the error handler is specified, the exception raised during the current promise completion
47 /// will be passed to it as the parameter. If the error handler returns without raising an
48 /// exception then the dependant promise will be resolved successfully, otherwise the exception
49 /// raised by the handler will be transmitted to the dependent promise. If the handler wants
50 /// to passthrough the original exception it needs to wrap the exception with
51 /// the <see cref="PromiseTransientException"/>. The handler may raise <see cref="OperationCanceledException"/>
52 /// to cancel the dependant promise, the innner exception specifies the reason why the promise
53 /// is canceled.
54 /// </para>
55 /// <para>
56 /// If the cancelation handler is specified and the current promise is cancelled then the dependent
57 /// promise will be resolved after the handler is executed. If the cancelation handler raises the
58 /// exception it will be passed to the dependent promise.
59 /// </para>
60 /// </remarks>
61 /* IPromise Then(Action success, Action<Exception> error, Action<Exception> cancel);
62 IPromise Then(Action success, Action<Exception> error);
63 IPromise Then(Action success);
64
65 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel);
66 IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error);
67 IPromise Chain(Func<IPromise> chained);*/
68
69 /// <summary>
70 30 /// Adds specified listeners to the current promise.
71 31 /// </summary>
72 32 /// <param name="success">The handler called on the successful promise completion.</param>
@@ -7,6 +7,10
7 7 <OutputType>Library</OutputType>
8 8 <RootNamespace>Implab</RootNamespace>
9 9 <AssemblyName>Implab</AssemblyName>
10 <ProductVersion>8.0.30703</ProductVersion>
11 <SchemaVersion>2.0</SchemaVersion>
12 <ReleaseVersion>0.2</ReleaseVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
10 14 </PropertyGroup>
11 15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 16 <DebugSymbols>true</DebugSymbols>
@@ -68,6 +72,7
68 72 <ItemGroup>
69 73 <Reference Include="System" />
70 74 <Reference Include="System.Xml" />
75 <Reference Include="mscorlib" />
71 76 </ItemGroup>
72 77 <ItemGroup>
73 78 <Compile Include="Component.cs" />
@@ -173,6 +178,8
173 178 <Compile Include="ICancellationToken.cs" />
174 179 <Compile Include="SuccessPromise.cs" />
175 180 <Compile Include="SuccessPromiseT.cs" />
181 <Compile Include="PromiseAwaiterT.cs" />
182 <Compile Include="PromiseAwaiter.cs" />
176 183 </ItemGroup>
177 184 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
178 185 <ItemGroup />
@@ -287,13 +287,10 namespace Implab {
287 287
288 288 #if NET_4_5
289 289
290 public static Task<T> GetTask<T>(this IPromise<T> that) {
290 public static PromiseAwaiter<T> GetAwaiter<T>(this IPromise<T> that) {
291 291 Safe.ArgumentNotNull(that, "that");
292 var tcs = new TaskCompletionSource<T>();
293 292
294 that.On(tcs.SetResult, tcs.SetException, r => tcs.SetCanceled());
295
296 return tcs.Task;
293 return new PromiseAwaiter<T>(that);
297 294 }
298 295
299 296 #endif
@@ -10,6 +10,7
10 10 <RootNamespace>MonoPlay</RootNamespace>
11 11 <AssemblyName>MonoPlay</AssemblyName>
12 12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
13 14 </PropertyGroup>
14 15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 16 <DebugSymbols>true</DebugSymbols>
@@ -7,6 +7,7 using System.Collections.Concurrent;
7 7 using System.Threading;
8 8 using Implab.JSON;
9 9 using System.IO;
10 using System.Threading.Tasks;
10 11
11 12 namespace MonoPlay {
12 13 class MainClass {
@@ -18,26 +19,22 namespace MonoPlay {
18 19
19 20 var t1 = Environment.TickCount;
20 21
21 for(int i =0; i < 1000000; i++)
22 using (var tw = new StringWriter()) {
23 var jw = new JSONWriter(tw);
24
25 jw.WriteValue("\r\nhere\tvalue\u0002\u0003");
26
27 //Console.WriteLine(tw);
28 }
29
30
22 DoWork().GetAwaiter().GetResult();
31 23
32 24 var t2 = Environment.TickCount;
33 25 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
34 26
35 27 }
36 28
37 static void DoTest() {
29 static IPromise<int> DoItem(int x) {
30 return Promise<int>.FromResult(x + 1);
31 }
38 32
39
40
33 static async Task<int> DoWork() {
34 var c = 0;
35 for (int i = 0; i < 10000000; i++)
36 c = await DoItem(c);
37 return c;
41 38 }
42 39
43 40 }
General Comments 0
You need to be logged in to leave comments. Login now