##// 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 <AssemblyName>Implab.Fx</AssemblyName>
12 <AssemblyName>Implab.Fx</AssemblyName>
13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14 <FileAlignment>512</FileAlignment>
14 <FileAlignment>512</FileAlignment>
15 <ReleaseVersion>0.2</ReleaseVersion>
15 </PropertyGroup>
16 </PropertyGroup>
16 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 <DebugSymbols>true</DebugSymbols>
18 <DebugSymbols>true</DebugSymbols>
@@ -845,6 +845,19 namespace Implab.Test {
845 Console.WriteLine(m);
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 <RootNamespace>Implab.Test</RootNamespace>
10 <RootNamespace>Implab.Test</RootNamespace>
11 <AssemblyName>Implab.Test</AssemblyName>
11 <AssemblyName>Implab.Test</AssemblyName>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
13 </PropertyGroup>
14 </PropertyGroup>
14 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
@@ -79,7 +79,6 Global
79 {2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
79 {2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
80 EndGlobalSection
80 EndGlobalSection
81 GlobalSection(MonoDevelopProperties) = preSolution
81 GlobalSection(MonoDevelopProperties) = preSolution
82 StartupItem = MonoPlay\MonoPlay.csproj
83 Policies = $0
82 Policies = $0
84 $0.CSharpFormattingPolicy = $1
83 $0.CSharpFormattingPolicy = $1
85 $1.IndentSwitchBody = True
84 $1.IndentSwitchBody = True
@@ -279,6 +278,8 Global
279 $34.NamingStyle = PascalCase
278 $34.NamingStyle = PascalCase
280 $34.IncludeInstanceMembers = True
279 $34.IncludeInstanceMembers = True
281 $34.IncludeStaticEntities = True
280 $34.IncludeStaticEntities = True
281 version = 0.2
282 StartupItem = MonoPlay\MonoPlay.csproj
282 EndGlobalSection
283 EndGlobalSection
283 GlobalSection(TestCaseManagementSettings) = postSolution
284 GlobalSection(TestCaseManagementSettings) = postSolution
284 CategoryFile = Implab.vsmdi
285 CategoryFile = Implab.vsmdi
@@ -27,46 +27,6 namespace Implab {
27 Exception Error { get; }
27 Exception Error { get; }
28
28
29 /// <summary>
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 /// Adds specified listeners to the current promise.
30 /// Adds specified listeners to the current promise.
71 /// </summary>
31 /// </summary>
72 /// <param name="success">The handler called on the successful promise completion.</param>
32 /// <param name="success">The handler called on the successful promise completion.</param>
@@ -7,6 +7,10
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
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 </PropertyGroup>
14 </PropertyGroup>
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
@@ -68,6 +72,7
68 <ItemGroup>
72 <ItemGroup>
69 <Reference Include="System" />
73 <Reference Include="System" />
70 <Reference Include="System.Xml" />
74 <Reference Include="System.Xml" />
75 <Reference Include="mscorlib" />
71 </ItemGroup>
76 </ItemGroup>
72 <ItemGroup>
77 <ItemGroup>
73 <Compile Include="Component.cs" />
78 <Compile Include="Component.cs" />
@@ -173,6 +178,8
173 <Compile Include="ICancellationToken.cs" />
178 <Compile Include="ICancellationToken.cs" />
174 <Compile Include="SuccessPromise.cs" />
179 <Compile Include="SuccessPromise.cs" />
175 <Compile Include="SuccessPromiseT.cs" />
180 <Compile Include="SuccessPromiseT.cs" />
181 <Compile Include="PromiseAwaiterT.cs" />
182 <Compile Include="PromiseAwaiter.cs" />
176 </ItemGroup>
183 </ItemGroup>
177 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
184 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
178 <ItemGroup />
185 <ItemGroup />
@@ -287,13 +287,10 namespace Implab {
287
287
288 #if NET_4_5
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 Safe.ArgumentNotNull(that, "that");
291 Safe.ArgumentNotNull(that, "that");
292 var tcs = new TaskCompletionSource<T>();
293
292
294 that.On(tcs.SetResult, tcs.SetException, r => tcs.SetCanceled());
293 return new PromiseAwaiter<T>(that);
295
296 return tcs.Task;
297 }
294 }
298
295
299 #endif
296 #endif
@@ -10,6 +10,7
10 <RootNamespace>MonoPlay</RootNamespace>
10 <RootNamespace>MonoPlay</RootNamespace>
11 <AssemblyName>MonoPlay</AssemblyName>
11 <AssemblyName>MonoPlay</AssemblyName>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
13 </PropertyGroup>
14 </PropertyGroup>
14 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
@@ -7,6 +7,7 using System.Collections.Concurrent;
7 using System.Threading;
7 using System.Threading;
8 using Implab.JSON;
8 using Implab.JSON;
9 using System.IO;
9 using System.IO;
10 using System.Threading.Tasks;
10
11
11 namespace MonoPlay {
12 namespace MonoPlay {
12 class MainClass {
13 class MainClass {
@@ -18,26 +19,22 namespace MonoPlay {
18
19
19 var t1 = Environment.TickCount;
20 var t1 = Environment.TickCount;
20
21
21 for(int i =0; i < 1000000; i++)
22 DoWork().GetAwaiter().GetResult();
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
31
23
32 var t2 = Environment.TickCount;
24 var t2 = Environment.TickCount;
33 Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
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
33 static async Task<int> DoWork() {
40
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