Mercurial > pub > ImplabNet
changeset 151:ec91a6dfa5b3 v2
Added support for 'await' operator to promises
author | cin |
---|---|
date | Thu, 04 Feb 2016 02:43:05 +0300 |
parents | 3258399cba83 |
children | 240aa6994018 |
files | Implab.Fx/Implab.Fx.csproj Implab.Test/AsyncTests.cs Implab.Test/Implab.Test.mono.csproj Implab.mono.sln Implab/IPromise.cs Implab/Implab.csproj Implab/PromiseAwaiter.cs Implab/PromiseAwaiterT.cs Implab/PromiseExtensions.cs MonoPlay/MonoPlay.csproj MonoPlay/Program.cs |
diffstat | 11 files changed, 93 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab.Fx/Implab.Fx.csproj Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab.Fx/Implab.Fx.csproj Thu Feb 04 02:43:05 2016 +0300 @@ -12,6 +12,7 @@ <AssemblyName>Implab.Fx</AssemblyName> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> + <ReleaseVersion>0.2</ReleaseVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols>
--- a/Implab.Test/AsyncTests.cs Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab.Test/AsyncTests.cs Thu Feb 04 02:43:05 2016 +0300 @@ -845,6 +845,19 @@ Console.WriteLine(m); } } + + #if NET_4_5 + + [TestMethod] + public async void TaskInteropTest() { + var promise = new Promise<int>(); + promise.Resolve(10); + var res = await promise; + + Assert.AreEqual(10, res); + } + + #endif } }
--- a/Implab.Test/Implab.Test.mono.csproj Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab.Test/Implab.Test.mono.csproj Thu Feb 04 02:43:05 2016 +0300 @@ -10,6 +10,7 @@ <RootNamespace>Implab.Test</RootNamespace> <AssemblyName>Implab.Test</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <ReleaseVersion>0.2</ReleaseVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols>
--- a/Implab.mono.sln Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab.mono.sln Thu Feb 04 02:43:05 2016 +0300 @@ -79,7 +79,6 @@ {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 @@ $34.NamingStyle = PascalCase $34.IncludeInstanceMembers = True $34.IncludeStaticEntities = True + version = 0.2 + StartupItem = MonoPlay\MonoPlay.csproj EndGlobalSection GlobalSection(TestCaseManagementSettings) = postSolution CategoryFile = Implab.vsmdi
--- a/Implab/IPromise.cs Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab/IPromise.cs Thu Feb 04 02:43:05 2016 +0300 @@ -27,46 +27,6 @@ Exception Error { get; } /// <summary> - /// Creates a new promise dependend on the current one and resolved on - /// executing the specified handlers. - /// </summary> - /// <param name="success">The handler called on the successful promise completion.</param> - /// <param name="error">The handler is called if an error while completing the promise occurred.</param> - /// <param name="cancel">The handler is called in case of promise cancellation.</param> - /// <returns>The newly created dependant promise.</returns> - /// <remarks> - /// <para> - /// 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. - /// </para> - /// <para> - /// 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 <see cref="PromiseTransientException"/>. The handler may raise <see cref="OperationCanceledException"/> - /// to cancel the dependant promise, the innner exception specifies the reason why the promise - /// is canceled. - /// </para> - /// <para> - /// 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. - /// </para> - /// </remarks> - /* IPromise Then(Action success, Action<Exception> error, Action<Exception> cancel); - IPromise Then(Action success, Action<Exception> error); - IPromise Then(Action success); - - IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error, Func<Exception, IPromise> cancel); - IPromise Chain(Func<IPromise> chained, Func<Exception, IPromise> error); - IPromise Chain(Func<IPromise> chained);*/ - - /// <summary> /// Adds specified listeners to the current promise. /// </summary> /// <param name="success">The handler called on the successful promise completion.</param>
--- a/Implab/Implab.csproj Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab/Implab.csproj Thu Feb 04 02:43:05 2016 +0300 @@ -7,6 +7,10 @@ <OutputType>Library</OutputType> <RootNamespace>Implab</RootNamespace> <AssemblyName>Implab</AssemblyName> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ReleaseVersion>0.2</ReleaseVersion> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -68,6 +72,7 @@ <ItemGroup> <Reference Include="System" /> <Reference Include="System.Xml" /> + <Reference Include="mscorlib" /> </ItemGroup> <ItemGroup> <Compile Include="Component.cs" /> @@ -173,6 +178,8 @@ <Compile Include="ICancellationToken.cs" /> <Compile Include="SuccessPromise.cs" /> <Compile Include="SuccessPromiseT.cs" /> + <Compile Include="PromiseAwaiterT.cs" /> + <Compile Include="PromiseAwaiter.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/PromiseAwaiter.cs Thu Feb 04 02:43:05 2016 +0300 @@ -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; + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/PromiseAwaiterT.cs Thu Feb 04 02:43:05 2016 +0300 @@ -0,0 +1,28 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Implab { + public struct PromiseAwaiter<T> : INotifyCompletion { + readonly IPromise<T> m_promise; + + public PromiseAwaiter(IPromise<T> 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; + } + } + } +} +
--- a/Implab/PromiseExtensions.cs Sat Dec 12 22:12:44 2015 +0300 +++ b/Implab/PromiseExtensions.cs Thu Feb 04 02:43:05 2016 +0300 @@ -287,13 +287,10 @@ #if NET_4_5 - public static Task<T> GetTask<T>(this IPromise<T> that) { + public static PromiseAwaiter<T> GetAwaiter<T>(this IPromise<T> that) { Safe.ArgumentNotNull(that, "that"); - var tcs = new TaskCompletionSource<T>(); - that.On(tcs.SetResult, tcs.SetException, r => tcs.SetCanceled()); - - return tcs.Task; + return new PromiseAwaiter<T>(that); } #endif
--- a/MonoPlay/MonoPlay.csproj Sat Dec 12 22:12:44 2015 +0300 +++ b/MonoPlay/MonoPlay.csproj Thu Feb 04 02:43:05 2016 +0300 @@ -10,6 +10,7 @@ <RootNamespace>MonoPlay</RootNamespace> <AssemblyName>MonoPlay</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <ReleaseVersion>0.2</ReleaseVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols>
--- a/MonoPlay/Program.cs Sat Dec 12 22:12:44 2015 +0300 +++ b/MonoPlay/Program.cs Thu Feb 04 02:43:05 2016 +0300 @@ -7,6 +7,7 @@ using System.Threading; using Implab.JSON; using System.IO; +using System.Threading.Tasks; namespace MonoPlay { class MainClass { @@ -18,26 +19,22 @@ 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<int> DoItem(int x) { + return Promise<int>.FromResult(x + 1); + } - - + static async Task<int> DoWork() { + var c = 0; + for (int i = 0; i < 10000000; i++) + c = await DoItem(c); + return c; } }