# HG changeset patch
# User cin
# Date 2016-02-03 23:43:05
# Node ID ec91a6dfa5b3f458072b9373a36c2e5ddb231c68
# Parent 3258399cba83ea4cd9b8565ef802cd0a9c29f98c
Added support for 'await' operator to promises
diff --git a/Implab.Fx/Implab.Fx.csproj b/Implab.Fx/Implab.Fx.csproj
--- a/Implab.Fx/Implab.Fx.csproj
+++ b/Implab.Fx/Implab.Fx.csproj
@@ -12,6 +12,7 @@
Implab.Fx
v4.0
512
+ 0.2
true
diff --git a/Implab.Test/AsyncTests.cs b/Implab.Test/AsyncTests.cs
--- a/Implab.Test/AsyncTests.cs
+++ b/Implab.Test/AsyncTests.cs
@@ -845,6 +845,19 @@ namespace Implab.Test {
Console.WriteLine(m);
}
}
+
+ #if NET_4_5
+
+ [TestMethod]
+ public async void TaskInteropTest() {
+ var promise = new Promise();
+ promise.Resolve(10);
+ var res = await promise;
+
+ Assert.AreEqual(10, res);
+ }
+
+ #endif
}
}
diff --git a/Implab.Test/Implab.Test.mono.csproj b/Implab.Test/Implab.Test.mono.csproj
--- a/Implab.Test/Implab.Test.mono.csproj
+++ b/Implab.Test/Implab.Test.mono.csproj
@@ -10,6 +10,7 @@
Implab.Test
Implab.Test
v4.5
+ 0.2
true
diff --git a/Implab.mono.sln b/Implab.mono.sln
--- a/Implab.mono.sln
+++ b/Implab.mono.sln
@@ -79,7 +79,6 @@ Global
{2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
- StartupItem = MonoPlay\MonoPlay.csproj
Policies = $0
$0.CSharpFormattingPolicy = $1
$1.IndentSwitchBody = True
@@ -279,6 +278,8 @@ Global
$34.NamingStyle = PascalCase
$34.IncludeInstanceMembers = True
$34.IncludeStaticEntities = True
+ version = 0.2
+ StartupItem = MonoPlay\MonoPlay.csproj
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Implab.vsmdi
diff --git a/Implab/IPromise.cs b/Implab/IPromise.cs
--- a/Implab/IPromise.cs
+++ b/Implab/IPromise.cs
@@ -27,46 +27,6 @@ namespace Implab {
Exception Error { get; }
///
- /// Creates a new promise dependend on the current one and resolved on
- /// executing the specified handlers.
- ///
- /// The handler called on the successful promise completion.
- /// The handler is called if an error while completing the promise occurred.
- /// The handler is called in case of promise cancellation.
- /// The newly created dependant promise.
- ///
- ///
- /// If the success handler is specified the dependend promise will be resolved after the handler is
- /// executed and the dependent promise will be linked to the current one, i.e. the cancellation
- /// of the dependent property will lead to the cancellation of the current promise. If the
- /// success handler isn't specified the dependent promise will not be linked to and
- /// will not be resolved after the successfull resolution of the current one.
- ///
- ///
- /// When the error handler is specified, the exception raised during the current promise completion
- /// will be passed to it as the parameter. If the error handler returns without raising an
- /// exception then the dependant promise will be resolved successfully, otherwise the exception
- /// raised by the handler will be transmitted to the dependent promise. If the handler wants
- /// to passthrough the original exception it needs to wrap the exception with
- /// the . The handler may raise
- /// to cancel the dependant promise, the innner exception specifies the reason why the promise
- /// is canceled.
- ///
- ///
- /// If the cancelation handler is specified and the current promise is cancelled then the dependent
- /// promise will be resolved after the handler is executed. If the cancelation handler raises the
- /// exception it will be passed to the dependent promise.
- ///
- ///
- /* IPromise Then(Action success, Action error, Action cancel);
- IPromise Then(Action success, Action error);
- IPromise Then(Action success);
-
- IPromise Chain(Func chained, Func error, Func cancel);
- IPromise Chain(Func chained, Func error);
- IPromise Chain(Func chained);*/
-
- ///
/// Adds specified listeners to the current promise.
///
/// The handler called on the successful promise completion.
diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj
--- a/Implab/Implab.csproj
+++ b/Implab/Implab.csproj
@@ -7,6 +7,10 @@
Library
Implab
Implab
+ 8.0.30703
+ 2.0
+ 0.2
+ v4.5
true
@@ -68,6 +72,7 @@
+
@@ -173,6 +178,8 @@
+
+
diff --git a/Implab/PromiseAwaiter.cs b/Implab/PromiseAwaiter.cs
new file mode 100644
--- /dev/null
+++ b/Implab/PromiseAwaiter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Implab {
+ public struct PromiseAwaiter : INotifyCompletion {
+ readonly IPromise m_promise;
+
+ public PromiseAwaiter(IPromise promise) {
+ m_promise = promise;
+ }
+
+ public void OnCompleted (Action continuation) {
+ if (m_promise != null)
+ m_promise.On(continuation, PromiseEventType.All);
+ }
+
+ public void GetResult() {
+ m_promise.Join();
+ }
+
+ public bool IsCompleted {
+ get {
+ return m_promise.IsResolved;
+ }
+ }
+ }
+}
+
diff --git a/Implab/PromiseAwaiterT.cs b/Implab/PromiseAwaiterT.cs
new file mode 100644
--- /dev/null
+++ b/Implab/PromiseAwaiterT.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Implab {
+ public struct PromiseAwaiter : INotifyCompletion {
+ readonly IPromise m_promise;
+
+ public PromiseAwaiter(IPromise promise) {
+ m_promise = promise;
+ }
+
+ public void OnCompleted (Action continuation) {
+ if (m_promise != null)
+ m_promise.On(continuation, PromiseEventType.All);
+ }
+
+ public T GetResult() {
+ return m_promise.Join();
+ }
+
+ public bool IsCompleted {
+ get {
+ return m_promise.IsResolved;
+ }
+ }
+ }
+}
+
diff --git a/Implab/PromiseExtensions.cs b/Implab/PromiseExtensions.cs
--- a/Implab/PromiseExtensions.cs
+++ b/Implab/PromiseExtensions.cs
@@ -287,13 +287,10 @@ namespace Implab {
#if NET_4_5
- public static Task GetTask(this IPromise that) {
+ public static PromiseAwaiter GetAwaiter(this IPromise that) {
Safe.ArgumentNotNull(that, "that");
- var tcs = new TaskCompletionSource();
- that.On(tcs.SetResult, tcs.SetException, r => tcs.SetCanceled());
-
- return tcs.Task;
+ return new PromiseAwaiter(that);
}
#endif
diff --git a/MonoPlay/MonoPlay.csproj b/MonoPlay/MonoPlay.csproj
--- a/MonoPlay/MonoPlay.csproj
+++ b/MonoPlay/MonoPlay.csproj
@@ -10,6 +10,7 @@
MonoPlay
MonoPlay
v4.5
+ 0.2
true
diff --git a/MonoPlay/Program.cs b/MonoPlay/Program.cs
--- a/MonoPlay/Program.cs
+++ b/MonoPlay/Program.cs
@@ -7,6 +7,7 @@ using System.Collections.Concurrent;
using System.Threading;
using Implab.JSON;
using System.IO;
+using System.Threading.Tasks;
namespace MonoPlay {
class MainClass {
@@ -18,26 +19,22 @@ namespace MonoPlay {
var t1 = Environment.TickCount;
- for(int i =0; i < 1000000; i++)
- using (var tw = new StringWriter()) {
- var jw = new JSONWriter(tw);
-
- jw.WriteValue("\r\nhere\tvalue\u0002\u0003");
-
- //Console.WriteLine(tw);
- }
-
-
+ DoWork().GetAwaiter().GetResult();
var t2 = Environment.TickCount;
Console.WriteLine("done: {0} ms, {1:.00} Mb, {2} GC", t2 - t1, GC.GetTotalMemory(false) / (1024*1024), GC.CollectionCount(0) );
}
- static void DoTest() {
+ static IPromise DoItem(int x) {
+ return Promise.FromResult(x + 1);
+ }
-
-
+ static async Task DoWork() {
+ var c = 0;
+ for (int i = 0; i < 10000000; i++)
+ c = await DoItem(c);
+ return c;
}
}