##// END OF EJS Templates
promises refactoring
cin -
r72:d67b95eddaf4 v2
parent child
Show More
@@ -0,0 +1,30
1 using System.Windows.Forms;
2 using System;
3
4
5 namespace Implab.Fx {
6 public class ControlBoundPromise<T> : Promise<T> {
7 readonly Control m_target;
8
9 public ControlBoundPromise(Control target) {
10 Safe.ArgumentNotNull(target, "target");
11
12 m_target = target;
13 }
14
15 public ControlBoundPromise(Control target, IPromise parent, bool cancellable)
16 : base(parent, cancellable) {
17 Safe.ArgumentNotNull(target, "target");
18
19 m_target = target;
20 }
21
22 protected override void InvokeHandler(HandlerDescriptor handler) {
23 if (m_target.InvokeRequired)
24 m_target.BeginInvoke(new Action<HandlerDescriptor>(base.InvokeHandler), handler);
25 else
26 base.InvokeHandler(handler);
27 }
28 }
29 }
30
@@ -0,0 +1,38
1 using System.Threading;
2
3 namespace Implab {
4 public static class PromiseExtensions {
5 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
6 var context = SynchronizationContext.Current;
7 if (context == null)
8 return that;
9
10 var p = new SyncContextPromise<T>(context, that, true);
11
12 that.Then(
13 x => p.Resolve(x),
14 e => {
15 p.Reject(e);
16 return default(T);
17 }
18 );
19 return p;
20 }
21
22 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
23 Safe.ArgumentNotNull(context, "context");
24
25 var p = new SyncContextPromise<T>(context, that, true);
26
27 that.Then(
28 x => p.Resolve(x),
29 e => {
30 p.Reject(e);
31 return default(T);
32 }
33 );
34 return p;
35 }
36 }
37 }
38
@@ -0,0 +1,22
1 using System.Threading;
2
3 namespace Implab {
4 public class SyncContextPromise<T> : Promise<T> {
5 readonly SynchronizationContext m_context;
6
7 public SyncContextPromise(SynchronizationContext context) {
8 Safe.ArgumentNotNull(context, "context");
9 m_context = context;
10 }
11
12 public SyncContextPromise(SynchronizationContext context, IPromise parent, bool cancellable)
13 : base(parent, cancellable) {
14 Safe.ArgumentNotNull(context, "context");
15 m_context = context;
16 }
17 protected override void InvokeHandler(HandlerDescriptor handler) {
18 m_context.Post(x => base.InvokeHandler(handler),null);
19 }
20 }
21 }
22
@@ -0,0 +1,33
1 using System;
2
3 namespace Implab {
4
5 [Serializable]
6 public class TransientPromiseException : Exception {
7 /// <summary>
8 /// Initializes a new instance of the <see cref="PromiseFailedException"/> class.
9 /// </summary>
10 /// <param name="inner">The exception that is the cause of the current exception.</param>
11 public TransientPromiseException(Exception inner) : base("The preceding promise has failed", inner) {
12 }
13
14 /// <summary>
15 /// Initializes a new instance of the <see cref="PromiseFailedException"/> class
16 /// </summary>
17 /// <param name="message">A <see cref="T:System.String"/> that describes the exception. </param>
18 /// <param name="inner">The exception that is the cause of the current exception. </param>
19 public TransientPromiseException(string message, Exception inner)
20 : base(message, inner) {
21 }
22
23 /// <summary>
24 /// Initializes a new instance of the <see cref="PromiseFailedException"/> class
25 /// </summary>
26 /// <param name="context">The contextual information about the source or destination.</param>
27 /// <param name="info">The object that holds the serialized object data.</param>
28 protected TransientPromiseException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
29 : base(info, context) {
30 }
31 }
32 }
33
@@ -1,94 +1,92
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>
6 <ProductVersion>8.0.30703</ProductVersion>
7 </ProductVersion>
8 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
9 <ProjectGuid>{2F31E405-E267-4195-A05D-574093C21209}</ProjectGuid>
8 <ProjectGuid>{2F31E405-E267-4195-A05D-574093C21209}</ProjectGuid>
10 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
11 <AppDesignerFolder>Properties</AppDesignerFolder>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
12 <RootNamespace>Implab.Fx.Test</RootNamespace>
11 <RootNamespace>Implab.Fx.Test</RootNamespace>
13 <AssemblyName>Implab.Fx.Test</AssemblyName>
12 <AssemblyName>Implab.Fx.Test</AssemblyName>
14 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
15 <FileAlignment>512</FileAlignment>
14 <FileAlignment>512</FileAlignment>
16 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
17 </PropertyGroup>
16 </PropertyGroup>
18 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19 <DebugSymbols>true</DebugSymbols>
18 <DebugSymbols>true</DebugSymbols>
20 <DebugType>full</DebugType>
19 <DebugType>full</DebugType>
21 <Optimize>false</Optimize>
20 <Optimize>false</Optimize>
22 <OutputPath>bin\Debug\</OutputPath>
21 <OutputPath>bin\Debug\</OutputPath>
23 <DefineConstants>DEBUG;TRACE</DefineConstants>
22 <DefineConstants>DEBUG;TRACE</DefineConstants>
24 <ErrorReport>prompt</ErrorReport>
23 <ErrorReport>prompt</ErrorReport>
25 <WarningLevel>4</WarningLevel>
24 <WarningLevel>4</WarningLevel>
26 </PropertyGroup>
25 </PropertyGroup>
27 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28 <DebugType>pdbonly</DebugType>
27 <DebugType>pdbonly</DebugType>
29 <Optimize>true</Optimize>
28 <Optimize>true</Optimize>
30 <OutputPath>bin\Release\</OutputPath>
29 <OutputPath>bin\Release\</OutputPath>
31 <DefineConstants>TRACE</DefineConstants>
30 <DefineConstants>TRACE</DefineConstants>
32 <ErrorReport>prompt</ErrorReport>
31 <ErrorReport>prompt</ErrorReport>
33 <WarningLevel>4</WarningLevel>
32 <WarningLevel>4</WarningLevel>
34 </PropertyGroup>
33 </PropertyGroup>
35 <ItemGroup>
34 <ItemGroup>
36 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
35 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
37 <Reference Include="System" />
36 <Reference Include="System" />
38 <Reference Include="System.Core">
37 <Reference Include="System.Core">
39 <RequiredTargetFramework>3.5</RequiredTargetFramework>
38 <RequiredTargetFramework>3.5</RequiredTargetFramework>
40 </Reference>
39 </Reference>
41 <Reference Include="System.Data" />
40 <Reference Include="System.Data" />
42 <Reference Include="System.Drawing" />
41 <Reference Include="System.Drawing" />
43 <Reference Include="System.Windows.Forms" />
42 <Reference Include="System.Windows.Forms" />
44 <Reference Include="System.Xml" />
43 <Reference Include="System.Xml" />
45 <Reference Include="WindowsBase" />
44 <Reference Include="WindowsBase" />
46 </ItemGroup>
45 </ItemGroup>
47 <ItemGroup>
46 <ItemGroup>
48 <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
49 <Visible>False</Visible>
50 </CodeAnalysisDependentAssemblyPaths>
51 </ItemGroup>
52 <ItemGroup>
53 <Compile Include="Properties\AssemblyInfo.cs" />
47 <Compile Include="Properties\AssemblyInfo.cs" />
54 <Compile Include="OverlayTest.cs" />
48 <Compile Include="OverlayTest.cs" />
55 <Compile Include="Sample\MainForm.cs">
49 <Compile Include="Sample\MainForm.cs">
56 <SubType>Form</SubType>
50 <SubType>Form</SubType>
57 </Compile>
51 </Compile>
58 <Compile Include="Sample\MainForm.Designer.cs">
52 <Compile Include="Sample\MainForm.Designer.cs">
59 <DependentUpon>MainForm.cs</DependentUpon>
53 <DependentUpon>MainForm.cs</DependentUpon>
60 </Compile>
54 </Compile>
61 <Compile Include="Sample\OverlayForm.cs">
55 <Compile Include="Sample\OverlayForm.cs">
62 <SubType>Form</SubType>
56 <SubType>Form</SubType>
63 </Compile>
57 </Compile>
64 <Compile Include="Sample\OverlayForm.Designer.cs">
58 <Compile Include="Sample\OverlayForm.Designer.cs">
65 <DependentUpon>OverlayForm.cs</DependentUpon>
59 <DependentUpon>OverlayForm.cs</DependentUpon>
66 </Compile>
60 </Compile>
67 </ItemGroup>
61 </ItemGroup>
68 <ItemGroup>
62 <ItemGroup>
69 <EmbeddedResource Include="Sample\MainForm.resx">
63 <EmbeddedResource Include="Sample\MainForm.resx">
70 <DependentUpon>MainForm.cs</DependentUpon>
64 <DependentUpon>MainForm.cs</DependentUpon>
65 <LogicalName>
66 </LogicalName>
71 </EmbeddedResource>
67 </EmbeddedResource>
72 <EmbeddedResource Include="Sample\OverlayForm.resx">
68 <EmbeddedResource Include="Sample\OverlayForm.resx">
73 <DependentUpon>OverlayForm.cs</DependentUpon>
69 <DependentUpon>OverlayForm.cs</DependentUpon>
70 <LogicalName>
71 </LogicalName>
74 </EmbeddedResource>
72 </EmbeddedResource>
75 </ItemGroup>
73 </ItemGroup>
76 <ItemGroup>
74 <ItemGroup>
77 <ProjectReference Include="..\Implab.Fx\Implab.Fx.csproj">
75 <ProjectReference Include="..\Implab.Fx\Implab.Fx.csproj">
78 <Project>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</Project>
76 <Project>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</Project>
79 <Name>Implab.Fx</Name>
77 <Name>Implab.Fx</Name>
80 </ProjectReference>
78 </ProjectReference>
81 <ProjectReference Include="..\Implab\Implab.csproj">
79 <ProjectReference Include="..\Implab\Implab.csproj">
82 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
80 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
83 <Name>Implab</Name>
81 <Name>Implab</Name>
84 </ProjectReference>
82 </ProjectReference>
85 </ItemGroup>
83 </ItemGroup>
86 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
84 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
87 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
85 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
88 Other similar extension points exist, see Microsoft.Common.targets.
86 Other similar extension points exist, see Microsoft.Common.targets.
89 <Target Name="BeforeBuild">
87 <Target Name="BeforeBuild">
90 </Target>
88 </Target>
91 <Target Name="AfterBuild">
89 <Target Name="AfterBuild">
92 </Target>
90 </Target>
93 -->
91 -->
94 </Project> No newline at end of file
92 </Project>
@@ -1,64 +1,65
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>8.0.30703</ProductVersion>
6 <ProductVersion>8.0.30703</ProductVersion>
7 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
8 <ProjectGuid>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</ProjectGuid>
8 <ProjectGuid>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</ProjectGuid>
9 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
11 <RootNamespace>Implab.Fx</RootNamespace>
11 <RootNamespace>Implab.Fx</RootNamespace>
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 </PropertyGroup>
15 </PropertyGroup>
16 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 <DebugSymbols>true</DebugSymbols>
17 <DebugSymbols>true</DebugSymbols>
18 <DebugType>full</DebugType>
18 <DebugType>full</DebugType>
19 <Optimize>false</Optimize>
19 <Optimize>false</Optimize>
20 <OutputPath>bin\Debug\</OutputPath>
20 <OutputPath>bin\Debug\</OutputPath>
21 <DefineConstants>DEBUG;TRACE</DefineConstants>
21 <DefineConstants>DEBUG;TRACE</DefineConstants>
22 <ErrorReport>prompt</ErrorReport>
22 <ErrorReport>prompt</ErrorReport>
23 <WarningLevel>4</WarningLevel>
23 <WarningLevel>4</WarningLevel>
24 </PropertyGroup>
24 </PropertyGroup>
25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <DebugType>pdbonly</DebugType>
26 <DebugType>pdbonly</DebugType>
27 <Optimize>true</Optimize>
27 <Optimize>true</Optimize>
28 <OutputPath>bin\Release\</OutputPath>
28 <OutputPath>bin\Release\</OutputPath>
29 <DefineConstants>TRACE</DefineConstants>
29 <DefineConstants>TRACE</DefineConstants>
30 <ErrorReport>prompt</ErrorReport>
30 <ErrorReport>prompt</ErrorReport>
31 <WarningLevel>4</WarningLevel>
31 <WarningLevel>4</WarningLevel>
32 </PropertyGroup>
32 </PropertyGroup>
33 <ItemGroup>
33 <ItemGroup>
34 <Reference Include="System" />
34 <Reference Include="System" />
35 <Reference Include="System.Core" />
35 <Reference Include="System.Core" />
36 <Reference Include="System.Drawing" />
36 <Reference Include="System.Drawing" />
37 <Reference Include="System.Windows.Forms" />
37 <Reference Include="System.Windows.Forms" />
38 <Reference Include="System.Xml.Linq" />
38 <Reference Include="System.Xml.Linq" />
39 <Reference Include="System.Data.DataSetExtensions" />
39 <Reference Include="System.Data.DataSetExtensions" />
40 <Reference Include="Microsoft.CSharp" />
40 <Reference Include="Microsoft.CSharp" />
41 <Reference Include="System.Data" />
41 <Reference Include="System.Data" />
42 <Reference Include="System.Xml" />
42 <Reference Include="System.Xml" />
43 </ItemGroup>
43 </ItemGroup>
44 <ItemGroup>
44 <ItemGroup>
45 <Compile Include="Animation.cs" />
45 <Compile Include="Animation.cs" />
46 <Compile Include="AnimationHelpers.cs" />
46 <Compile Include="AnimationHelpers.cs" />
47 <Compile Include="PromiseHelpers.cs" />
47 <Compile Include="PromiseHelpers.cs" />
48 <Compile Include="Properties\AssemblyInfo.cs" />
48 <Compile Include="Properties\AssemblyInfo.cs" />
49 <Compile Include="ControlBoundPromise.cs" />
49 </ItemGroup>
50 </ItemGroup>
50 <ItemGroup>
51 <ItemGroup>
51 <ProjectReference Include="..\Implab\Implab.csproj">
52 <ProjectReference Include="..\Implab\Implab.csproj">
52 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
53 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
53 <Name>Implab</Name>
54 <Name>Implab</Name>
54 </ProjectReference>
55 </ProjectReference>
55 </ItemGroup>
56 </ItemGroup>
56 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
57 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
57 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
58 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
58 Other similar extension points exist, see Microsoft.Common.targets.
59 Other similar extension points exist, see Microsoft.Common.targets.
59 <Target Name="BeforeBuild">
60 <Target Name="BeforeBuild">
60 </Target>
61 </Target>
61 <Target Name="AfterBuild">
62 <Target Name="AfterBuild">
62 </Target>
63 </Target>
63 -->
64 -->
64 </Project> No newline at end of file
65 </Project>
@@ -1,95 +1,87
1 using System;
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows.Forms;
2 using System.Windows.Forms;
6 using System.Threading;
3 using System.Threading;
7
4
8 namespace Implab.Fx
5 namespace Implab.Fx
9 {
6 {
10 public static class PromiseHelpers
7 public static class PromiseHelpers
11 {
8 {
12 /// <summary>
9 /// <summary>
13 /// ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ элСмСнта управлСния.
10 /// ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ элСмСнта управлСния.
14 /// </summary>
11 /// </summary>
15 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания</typeparam>
12 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания</typeparam>
16 /// <param name="that">Π˜ΡΡ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅</param>
13 /// <param name="that">Π˜ΡΡ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅</param>
17 /// <param name="ctl">Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ управлСния</param>
14 /// <param name="ctl">Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ управлСния</param>
18 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ элСмСнта управлСния.</returns>
15 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ элСмСнта управлСния.</returns>
19 /// <exception cref="ArgumentNullException">ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ <c>null</c>.</exception>
16 /// <exception cref="ArgumentNullException">ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ <c>null</c>.</exception>
20 /// <example>
17 /// <example>
21 /// client
18 /// client
22 /// .Get("description.txt") // returns a promise
19 /// .Get("description.txt") // returns a promise
23 /// .DirectToControl(m_ctl) // handle the promise in the thread of the control
20 /// .DirectToControl(m_ctl) // handle the promise in the thread of the control
24 /// .Then(
21 /// .Then(
25 /// description => m_ctl.Text = description // now it's safe
22 /// description => m_ctl.Text = description // now it's safe
26 /// )
23 /// )
27 /// </example>
24 /// </example>
28 public static Promise<T> DispatchToControl<T>(this Promise<T> that, Control ctl)
25 public static Promise<T> DispatchToControl<T>(this Promise<T> that, Control ctl)
29 {
26 {
30 if (that == null)
27 if (that == null)
31 throw new ArgumentNullException("that");
28 throw new ArgumentNullException("that");
32 if (ctl == null)
29 if (ctl == null)
33 throw new ArgumentNullException("ctl");
30 throw new ArgumentNullException("ctl");
34
31
35 var directed = new Promise<T>();
32 var directed = new ControlBoundPromise<T>(ctl,that,true);
36
33
37 that.Then(
34 that.Then(
38 res =>
35 directed.Resolve,
39 {
40 if (ctl.InvokeRequired)
41 ctl.Invoke(new Action<T>(directed.Resolve), res);
42 else
43 directed.Resolve(res);
44 },
45 err =>
36 err =>
46 {
37 {
47 if (ctl.InvokeRequired)
38 directed.Reject(err);
48 ctl.Invoke(new Action<Exception>(directed.Reject), err);
39 return default(T);
49 else
50 directed.Reject(err);
51 }
40 }
52 );
41 );
53
42
54 return directed;
43 return directed;
55 }
44 }
56
45
57 /// <summary>
46 /// <summary>
58 /// НаправляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, Ссли Ρƒ Π½Π΅Π³ΠΎ сущСствуСт контСкст синхронизации.
47 /// НаправляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, Ссли Ρƒ Π½Π΅Π³ΠΎ сущСствуСт контСкст синхронизации.
59 /// </summary>
48 /// </summary>
60 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания.</typeparam>
49 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания.</typeparam>
61 /// <param name="that">ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅.</param>
50 /// <param name="that">ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅.</param>
62 /// <returns>ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.</returns>
51 /// <returns>ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.</returns>
63 public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
52 public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
64 {
53 {
65 var sync = SynchronizationContext.Current;
54 var sync = SynchronizationContext.Current;
66 if (sync == null)
55 if (sync == null)
67 throw new InvalidOperationException("The current thread doesn't have a syncronization context");
56 throw new InvalidOperationException("The current thread doesn't have a syncronization context");
68 return DispatchToSyncContext(that, sync);
57 return DispatchToSyncContext(that, sync);
69 }
58 }
70
59
71 /// <summary>
60 /// <summary>
72 /// НаправляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ контСкст синхронизации.
61 /// НаправляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ обСщания Π² ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ контСкст синхронизации.
73 /// </summary>
62 /// </summary>
74 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания.</typeparam>
63 /// <typeparam name="T">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° обСщания.</typeparam>
75 /// <param name="that">ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ трСбуСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС синхронизации.</param>
64 /// <param name="that">ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ трСбуСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС синхронизации.</param>
76 /// <param name="sync">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ синхронизации Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.</param>
65 /// <param name="sync">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ синхронизации Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅.</param>
77 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС.</returns>
66 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС.</returns>
78 public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
67 public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
79 {
68 {
80 if (that == null)
69 if (that == null)
81 throw new ArgumentNullException("that");
70 throw new ArgumentNullException("that");
82 if (sync == null)
71 if (sync == null)
83 throw new ArgumentNullException("sync");
72 throw new ArgumentNullException("sync");
84
73
85 var d = new Promise<T>();
74 var d = new Promise<T>();
86
75
87 that.Then(
76 that.Then(
88 res => sync.Post(state => d.Resolve(res), null),
77 res => sync.Post(state => d.Resolve(res), null),
89 err => sync.Post(state => d.Reject(err), null)
78 err => {
79 sync.Post(state => d.Reject(err), null);
80 return default(T);
81 }
90 );
82 );
91
83
92 return d;
84 return d;
93 }
85 }
94 }
86 }
95 }
87 }
@@ -1,66 +1,60
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>
6 <ProductVersion>8.0.30703</ProductVersion>
7 </ProductVersion>
8 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
9 <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid>
8 <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid>
10 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
11 <AppDesignerFolder>Properties</AppDesignerFolder>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
12 <RootNamespace>Implab.Test</RootNamespace>
11 <RootNamespace>Implab.Test</RootNamespace>
13 <AssemblyName>Implab.Test</AssemblyName>
12 <AssemblyName>Implab.Test</AssemblyName>
14 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
15 <FileAlignment>512</FileAlignment>
14 <FileAlignment>512</FileAlignment>
16 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
17 </PropertyGroup>
16 </PropertyGroup>
18 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19 <DebugSymbols>true</DebugSymbols>
18 <DebugSymbols>true</DebugSymbols>
20 <DebugType>full</DebugType>
19 <DebugType>full</DebugType>
21 <Optimize>false</Optimize>
20 <Optimize>false</Optimize>
22 <OutputPath>bin\Debug\</OutputPath>
21 <OutputPath>bin\Debug\</OutputPath>
23 <DefineConstants>DEBUG;TRACE</DefineConstants>
22 <DefineConstants>DEBUG;TRACE</DefineConstants>
24 <ErrorReport>prompt</ErrorReport>
23 <ErrorReport>prompt</ErrorReport>
25 <WarningLevel>4</WarningLevel>
24 <WarningLevel>4</WarningLevel>
26 </PropertyGroup>
25 </PropertyGroup>
27 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28 <DebugType>pdbonly</DebugType>
27 <DebugType>pdbonly</DebugType>
29 <Optimize>true</Optimize>
28 <Optimize>true</Optimize>
30 <OutputPath>bin\Release\</OutputPath>
29 <OutputPath>bin\Release\</OutputPath>
31 <DefineConstants>TRACE</DefineConstants>
30 <DefineConstants>TRACE</DefineConstants>
32 <ErrorReport>prompt</ErrorReport>
31 <ErrorReport>prompt</ErrorReport>
33 <WarningLevel>4</WarningLevel>
32 <WarningLevel>4</WarningLevel>
34 </PropertyGroup>
33 </PropertyGroup>
35 <ItemGroup>
34 <ItemGroup>
36 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
35 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
37 <Reference Include="System" />
36 <Reference Include="System" />
38 <Reference Include="System.Core">
37 <Reference Include="System.Core">
39 <RequiredTargetFramework>3.5</RequiredTargetFramework>
38 <RequiredTargetFramework>3.5</RequiredTargetFramework>
40 </Reference>
39 </Reference>
41 </ItemGroup>
40 </ItemGroup>
42 <ItemGroup>
41 <ItemGroup>
43 <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
44 <Visible>False</Visible>
45 </CodeAnalysisDependentAssemblyPaths>
46 </ItemGroup>
47 <ItemGroup>
48 <Compile Include="AsyncTests.cs" />
42 <Compile Include="AsyncTests.cs" />
49 <Compile Include="PromiseHelper.cs" />
43 <Compile Include="PromiseHelper.cs" />
50 <Compile Include="Properties\AssemblyInfo.cs" />
44 <Compile Include="Properties\AssemblyInfo.cs" />
51 </ItemGroup>
45 </ItemGroup>
52 <ItemGroup>
46 <ItemGroup>
53 <ProjectReference Include="..\Implab\Implab.csproj">
47 <ProjectReference Include="..\Implab\Implab.csproj">
54 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
48 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
55 <Name>Implab</Name>
49 <Name>Implab</Name>
56 </ProjectReference>
50 </ProjectReference>
57 </ItemGroup>
51 </ItemGroup>
58 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
52 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
59 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
53 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
60 Other similar extension points exist, see Microsoft.Common.targets.
54 Other similar extension points exist, see Microsoft.Common.targets.
61 <Target Name="BeforeBuild">
55 <Target Name="BeforeBuild">
62 </Target>
56 </Target>
63 <Target Name="AfterBuild">
57 <Target Name="AfterBuild">
64 </Target>
58 </Target>
65 -->
59 -->
66 </Project> No newline at end of file
60 </Project>
@@ -1,51 +1,252
1 ο»Ώ
1 ο»Ώ
2 Microsoft Visual Studio Solution File, Format Version 11.00
2 Microsoft Visual Studio Solution File, Format Version 11.00
3 # Visual Studio 2010
3 # Visual Studio 2010
4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
5 EndProject
5 EndProject
6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
7 ProjectSection(SolutionItems) = preProject
7 ProjectSection(SolutionItems) = preProject
8 Implab.vsmdi = Implab.vsmdi
8 Implab.vsmdi = Implab.vsmdi
9 Local.testsettings = Local.testsettings
9 Local.testsettings = Local.testsettings
10 TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
10 TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
11 EndProjectSection
11 EndProjectSection
12 EndProject
12 EndProject
13 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test", "Implab.Test\Implab.Test.csproj", "{63F92C0C-61BF-48C0-A377-8D67C3C661D0}"
13 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test", "Implab.Test\Implab.Test.csproj", "{63F92C0C-61BF-48C0-A377-8D67C3C661D0}"
14 EndProject
14 EndProject
15 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
15 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
16 EndProject
16 EndProject
17 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}"
17 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}"
18 EndProject
18 EndProject
19 Global
19 Global
20 GlobalSection(TestCaseManagementSettings) = postSolution
21 CategoryFile = Implab.vsmdi
22 EndGlobalSection
23 GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 Debug|Any CPU = Debug|Any CPU
21 Debug|Any CPU = Debug|Any CPU
25 Release|Any CPU = Release|Any CPU
22 Release|Any CPU = Release|Any CPU
26 EndGlobalSection
23 EndGlobalSection
27 GlobalSection(ProjectConfigurationPlatforms) = postSolution
24 GlobalSection(ProjectConfigurationPlatforms) = postSolution
28 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
32 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
36 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
28 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
40 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
32 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
33 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
37 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
41 EndGlobalSection
42 GlobalSection(NestedProjects) = preSolution
43 EndGlobalSection
44 GlobalSection(MonoDevelopProperties) = preSolution
45 StartupItem = Implab\Implab.csproj
46 Policies = $0
47 $0.CSharpFormattingPolicy = $1
48 $1.IndentSwitchBody = True
49 $1.NamespaceBraceStyle = EndOfLine
50 $1.ClassBraceStyle = EndOfLine
51 $1.InterfaceBraceStyle = EndOfLine
52 $1.StructBraceStyle = EndOfLine
53 $1.EnumBraceStyle = EndOfLine
54 $1.MethodBraceStyle = EndOfLine
55 $1.ConstructorBraceStyle = EndOfLine
56 $1.DestructorBraceStyle = EndOfLine
57 $1.BeforeMethodDeclarationParentheses = False
58 $1.BeforeMethodCallParentheses = False
59 $1.BeforeConstructorDeclarationParentheses = False
60 $1.NewLineBeforeConstructorInitializerColon = NewLine
61 $1.NewLineAfterConstructorInitializerColon = SameLine
62 $1.BeforeIndexerDeclarationBracket = False
63 $1.BeforeDelegateDeclarationParentheses = False
64 $1.NewParentheses = False
65 $1.SpacesBeforeBrackets = False
66 $1.inheritsSet = Mono
67 $1.inheritsScope = text/x-csharp
68 $1.scope = text/x-csharp
69 $0.TextStylePolicy = $2
70 $2.FileWidth = 120
71 $2.EolMarker = Unix
72 $2.inheritsSet = VisualStudio
73 $2.inheritsScope = text/plain
74 $2.scope = text/x-csharp
75 $0.DotNetNamingPolicy = $3
76 $3.DirectoryNamespaceAssociation = PrefixedHierarchical
77 $3.ResourceNamePolicy = MSBuild
78 $0.TextStylePolicy = $4
79 $4.FileWidth = 120
80 $4.TabsToSpaces = False
81 $4.inheritsSet = VisualStudio
82 $4.inheritsScope = text/plain
83 $4.scope = application/xml
84 $0.XmlFormattingPolicy = $5
85 $5.inheritsSet = Mono
86 $5.inheritsScope = application/xml
87 $5.scope = application/xml
88 $0.TextStylePolicy = $6
89 $6.FileWidth = 120
90 $6.TabsToSpaces = False
91 $6.inheritsSet = VisualStudio
92 $6.inheritsScope = text/plain
93 $6.scope = text/plain
94 $0.NameConventionPolicy = $7
95 $7.Rules = $8
96 $8.NamingRule = $9
97 $9.Name = Namespaces
98 $9.AffectedEntity = Namespace
99 $9.VisibilityMask = VisibilityMask
100 $9.NamingStyle = PascalCase
101 $9.IncludeInstanceMembers = True
102 $9.IncludeStaticEntities = True
103 $8.NamingRule = $10
104 $10.Name = Types
105 $10.AffectedEntity = Class, Struct, Enum, Delegate
106 $10.VisibilityMask = VisibilityMask
107 $10.NamingStyle = PascalCase
108 $10.IncludeInstanceMembers = True
109 $10.IncludeStaticEntities = True
110 $8.NamingRule = $11
111 $11.Name = Interfaces
112 $11.RequiredPrefixes = $12
113 $12.String = I
114 $11.AffectedEntity = Interface
115 $11.VisibilityMask = VisibilityMask
116 $11.NamingStyle = PascalCase
117 $11.IncludeInstanceMembers = True
118 $11.IncludeStaticEntities = True
119 $8.NamingRule = $13
120 $13.Name = Attributes
121 $13.RequiredSuffixes = $14
122 $14.String = Attribute
123 $13.AffectedEntity = CustomAttributes
124 $13.VisibilityMask = VisibilityMask
125 $13.NamingStyle = PascalCase
126 $13.IncludeInstanceMembers = True
127 $13.IncludeStaticEntities = True
128 $8.NamingRule = $15
129 $15.Name = Event Arguments
130 $15.RequiredSuffixes = $16
131 $16.String = EventArgs
132 $15.AffectedEntity = CustomEventArgs
133 $15.VisibilityMask = VisibilityMask
134 $15.NamingStyle = PascalCase
135 $15.IncludeInstanceMembers = True
136 $15.IncludeStaticEntities = True
137 $8.NamingRule = $17
138 $17.Name = Exceptions
139 $17.RequiredSuffixes = $18
140 $18.String = Exception
141 $17.AffectedEntity = CustomExceptions
142 $17.VisibilityMask = VisibilityMask
143 $17.NamingStyle = PascalCase
144 $17.IncludeInstanceMembers = True
145 $17.IncludeStaticEntities = True
146 $8.NamingRule = $19
147 $19.Name = Methods
148 $19.AffectedEntity = Methods
149 $19.VisibilityMask = VisibilityMask
150 $19.NamingStyle = PascalCase
151 $19.IncludeInstanceMembers = True
152 $19.IncludeStaticEntities = True
153 $8.NamingRule = $20
154 $20.Name = Static Readonly Fields
155 $20.AffectedEntity = ReadonlyField
156 $20.VisibilityMask = Internal, Protected, Public
157 $20.NamingStyle = CamelCase
158 $20.IncludeInstanceMembers = False
159 $20.IncludeStaticEntities = True
160 $8.NamingRule = $21
161 $21.Name = Fields (Non Private)
162 $21.AffectedEntity = Field
163 $21.VisibilityMask = Internal, Public
164 $21.NamingStyle = CamelCase
165 $21.IncludeInstanceMembers = True
166 $21.IncludeStaticEntities = True
167 $8.NamingRule = $22
168 $22.Name = ReadOnly Fields (Non Private)
169 $22.AffectedEntity = ReadonlyField
170 $22.VisibilityMask = Internal, Public
171 $22.NamingStyle = CamelCase
172 $22.IncludeInstanceMembers = True
173 $22.IncludeStaticEntities = False
174 $8.NamingRule = $23
175 $23.Name = Fields (Private)
176 $23.RequiredPrefixes = $24
177 $24.String = m_
178 $23.AffectedEntity = Field, ReadonlyField
179 $23.VisibilityMask = Private, Protected
180 $23.NamingStyle = CamelCase
181 $23.IncludeInstanceMembers = True
182 $23.IncludeStaticEntities = False
183 $8.NamingRule = $25
184 $25.Name = Static Fields (Private)
185 $25.RequiredPrefixes = $26
186 $26.String = _
187 $25.AffectedEntity = Field
188 $25.VisibilityMask = Private
189 $25.NamingStyle = CamelCase
190 $25.IncludeInstanceMembers = False
191 $25.IncludeStaticEntities = True
192 $8.NamingRule = $27
193 $27.Name = ReadOnly Fields (Private)
194 $27.RequiredPrefixes = $28
195 $28.String = m_
196 $27.AffectedEntity = ReadonlyField
197 $27.VisibilityMask = Private, Protected
198 $27.NamingStyle = CamelCase
199 $27.IncludeInstanceMembers = True
200 $27.IncludeStaticEntities = False
201 $8.NamingRule = $29
202 $29.Name = Constant Fields
203 $29.AffectedEntity = ConstantField
204 $29.VisibilityMask = VisibilityMask
205 $29.NamingStyle = AllUpper
206 $29.IncludeInstanceMembers = True
207 $29.IncludeStaticEntities = True
208 $8.NamingRule = $30
209 $30.Name = Properties
210 $30.AffectedEntity = Property
211 $30.VisibilityMask = VisibilityMask
212 $30.NamingStyle = PascalCase
213 $30.IncludeInstanceMembers = True
214 $30.IncludeStaticEntities = True
215 $8.NamingRule = $31
216 $31.Name = Events
217 $31.AffectedEntity = Event
218 $31.VisibilityMask = VisibilityMask
219 $31.NamingStyle = PascalCase
220 $31.IncludeInstanceMembers = True
221 $31.IncludeStaticEntities = True
222 $8.NamingRule = $32
223 $32.Name = Enum Members
224 $32.AffectedEntity = EnumMember
225 $32.VisibilityMask = VisibilityMask
226 $32.NamingStyle = PascalCase
227 $32.IncludeInstanceMembers = True
228 $32.IncludeStaticEntities = True
229 $8.NamingRule = $33
230 $33.Name = Parameters
231 $33.AffectedEntity = Parameter, LocalVariable
232 $33.VisibilityMask = VisibilityMask
233 $33.NamingStyle = CamelCase
234 $33.IncludeInstanceMembers = True
235 $33.IncludeStaticEntities = True
236 $8.NamingRule = $34
237 $34.Name = Type Parameters
238 $34.RequiredPrefixes = $35
239 $35.String = T
240 $34.AffectedEntity = TypeParameter
241 $34.VisibilityMask = VisibilityMask
242 $34.NamingStyle = PascalCase
243 $34.IncludeInstanceMembers = True
244 $34.IncludeStaticEntities = True
245 EndGlobalSection
246 GlobalSection(TestCaseManagementSettings) = postSolution
247 CategoryFile = Implab.vsmdi
44 EndGlobalSection
248 EndGlobalSection
45 GlobalSection(SolutionProperties) = preSolution
249 GlobalSection(SolutionProperties) = preSolution
46 HideSolutionNode = FALSE
250 HideSolutionNode = FALSE
47 EndGlobalSection
251 EndGlobalSection
48 GlobalSection(MonoDevelopProperties) = preSolution
49 StartupItem = Implab\Implab.csproj
50 EndGlobalSection
51 EndGlobal
252 EndGlobal
@@ -1,31 +1,29
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5
5
6 namespace Implab
6 namespace Implab
7 {
7 {
8 public interface IPromise<T>: IPromise
8 public interface IPromise<T>: IPromise
9 {
9 {
10
10
11 new T Join();
11 new T Join();
12 new T Join(int timeout);
12 new T Join(int timeout);
13
13
14 IPromise<T> Then(ResultHandler<T> success, ErrorHandler error);
15 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
14 IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error);
16 IPromise<T> Then(ResultHandler<T> success);
15 IPromise<T> Then(ResultHandler<T> success);
17 new IPromise<T> Error(ErrorHandler error);
18 IPromise<T> Error(ErrorHandler<T> error);
16 IPromise<T> Error(ErrorHandler<T> error);
19
17
20 IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler error);
18 IPromise<T2> Map<T2>(ResultMapper<T,T2> mapper, ErrorHandler<T> error);
21 IPromise<T2> Map<T2>(ResultMapper<T, T2> mapper);
19 IPromise<T2> Map<T2>(ResultMapper<T, T2> mapper);
22
20
23 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler error);
21 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained, ErrorHandler<T> error);
24 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained);
22 IPromise<T2> Chain<T2>(ChainedOperation<T, T2> chained);
25
23
26 new IPromise<T> Cancelled(Action handler);
24 new IPromise<T> Cancelled(Action handler);
27 new IPromise<T> Finally(Action handler);
25 new IPromise<T> Finally(Action handler);
28 new IPromise<T> Anyway(Action handler);
26 new IPromise<T> Anyway(Action handler);
29
27
30 }
28 }
31 }
29 }
@@ -1,105 +1,179
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
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>
10 </PropertyGroup>
12 </PropertyGroup>
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 <DebugSymbols>true</DebugSymbols>
14 <DebugSymbols>true</DebugSymbols>
13 <DebugType>full</DebugType>
15 <DebugType>full</DebugType>
14 <Optimize>false</Optimize>
16 <Optimize>false</Optimize>
15 <OutputPath>bin\Debug</OutputPath>
17 <OutputPath>bin\Debug</OutputPath>
16 <DefineConstants>TRACE;DEBUG;</DefineConstants>
18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
17 <ErrorReport>prompt</ErrorReport>
19 <ErrorReport>prompt</ErrorReport>
18 <WarningLevel>4</WarningLevel>
20 <WarningLevel>4</WarningLevel>
19 <ConsolePause>false</ConsolePause>
21 <ConsolePause>false</ConsolePause>
20 <RunCodeAnalysis>true</RunCodeAnalysis>
22 <RunCodeAnalysis>true</RunCodeAnalysis>
21 </PropertyGroup>
23 </PropertyGroup>
22 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23 <DebugType>full</DebugType>
25 <DebugType>full</DebugType>
24 <Optimize>true</Optimize>
26 <Optimize>true</Optimize>
25 <OutputPath>bin\Release</OutputPath>
27 <OutputPath>bin\Release</OutputPath>
26 <ErrorReport>prompt</ErrorReport>
28 <ErrorReport>prompt</ErrorReport>
27 <WarningLevel>4</WarningLevel>
29 <WarningLevel>4</WarningLevel>
28 <ConsolePause>false</ConsolePause>
30 <ConsolePause>false</ConsolePause>
29 </PropertyGroup>
31 </PropertyGroup>
30 <ItemGroup>
32 <ItemGroup>
31 <Reference Include="System" />
33 <Reference Include="System" />
32 <Reference Include="System.Xml" />
34 <Reference Include="System.Xml" />
33 </ItemGroup>
35 </ItemGroup>
34 <ItemGroup>
36 <ItemGroup>
35 <Compile Include="Component.cs" />
37 <Compile Include="Component.cs" />
36 <Compile Include="CustomEqualityComparer.cs" />
38 <Compile Include="CustomEqualityComparer.cs" />
37 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
39 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
38 <Compile Include="Diagnostics\EventText.cs" />
40 <Compile Include="Diagnostics\EventText.cs" />
39 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
41 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
40 <Compile Include="Diagnostics\LogChannel.cs" />
42 <Compile Include="Diagnostics\LogChannel.cs" />
41 <Compile Include="Diagnostics\LogicalOperation.cs" />
43 <Compile Include="Diagnostics\LogicalOperation.cs" />
42 <Compile Include="Diagnostics\TextFileListener.cs" />
44 <Compile Include="Diagnostics\TextFileListener.cs" />
43 <Compile Include="Diagnostics\TextListenerBase.cs" />
45 <Compile Include="Diagnostics\TextListenerBase.cs" />
44 <Compile Include="Diagnostics\TraceLog.cs" />
46 <Compile Include="Diagnostics\TraceLog.cs" />
45 <Compile Include="Diagnostics\TraceContext.cs" />
47 <Compile Include="Diagnostics\TraceContext.cs" />
46 <Compile Include="Diagnostics\TraceEvent.cs" />
48 <Compile Include="Diagnostics\TraceEvent.cs" />
47 <Compile Include="Diagnostics\TraceEventType.cs" />
49 <Compile Include="Diagnostics\TraceEventType.cs" />
48 <Compile Include="Disposable.cs" />
50 <Compile Include="Disposable.cs" />
49 <Compile Include="ICancellable.cs" />
51 <Compile Include="ICancellable.cs" />
50 <Compile Include="IProgressHandler.cs" />
52 <Compile Include="IProgressHandler.cs" />
51 <Compile Include="IProgressNotifier.cs" />
53 <Compile Include="IProgressNotifier.cs" />
52 <Compile Include="IPromiseT.cs" />
54 <Compile Include="IPromiseT.cs" />
53 <Compile Include="IPromise.cs" />
55 <Compile Include="IPromise.cs" />
54 <Compile Include="IServiceLocator.cs" />
56 <Compile Include="IServiceLocator.cs" />
55 <Compile Include="ITaskController.cs" />
57 <Compile Include="ITaskController.cs" />
56 <Compile Include="JSON\JSONElementContext.cs" />
58 <Compile Include="JSON\JSONElementContext.cs" />
57 <Compile Include="JSON\JSONElementType.cs" />
59 <Compile Include="JSON\JSONElementType.cs" />
58 <Compile Include="JSON\JSONGrammar.cs" />
60 <Compile Include="JSON\JSONGrammar.cs" />
59 <Compile Include="JSON\JSONParser.cs" />
61 <Compile Include="JSON\JSONParser.cs" />
60 <Compile Include="JSON\JSONScanner.cs" />
62 <Compile Include="JSON\JSONScanner.cs" />
61 <Compile Include="JSON\JsonTokenType.cs" />
63 <Compile Include="JSON\JsonTokenType.cs" />
62 <Compile Include="JSON\JSONWriter.cs" />
64 <Compile Include="JSON\JSONWriter.cs" />
63 <Compile Include="JSON\JSONXmlReader.cs" />
65 <Compile Include="JSON\JSONXmlReader.cs" />
64 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
66 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
65 <Compile Include="JSON\StringTranslator.cs" />
67 <Compile Include="JSON\StringTranslator.cs" />
66 <Compile Include="Parallels\DispatchPool.cs" />
68 <Compile Include="Parallels\DispatchPool.cs" />
67 <Compile Include="Parallels\ArrayTraits.cs" />
69 <Compile Include="Parallels\ArrayTraits.cs" />
68 <Compile Include="Parallels\MTQueue.cs" />
70 <Compile Include="Parallels\MTQueue.cs" />
69 <Compile Include="Parallels\WorkerPool.cs" />
71 <Compile Include="Parallels\WorkerPool.cs" />
70 <Compile Include="Parsing\Alphabet.cs" />
72 <Compile Include="Parsing\Alphabet.cs" />
71 <Compile Include="Parsing\AlphabetBase.cs" />
73 <Compile Include="Parsing\AlphabetBase.cs" />
72 <Compile Include="Parsing\AltToken.cs" />
74 <Compile Include="Parsing\AltToken.cs" />
73 <Compile Include="Parsing\BinaryToken.cs" />
75 <Compile Include="Parsing\BinaryToken.cs" />
74 <Compile Include="Parsing\CatToken.cs" />
76 <Compile Include="Parsing\CatToken.cs" />
75 <Compile Include="Parsing\CDFADefinition.cs" />
77 <Compile Include="Parsing\CDFADefinition.cs" />
76 <Compile Include="Parsing\DFABuilder.cs" />
78 <Compile Include="Parsing\DFABuilder.cs" />
77 <Compile Include="Parsing\DFADefinitionBase.cs" />
79 <Compile Include="Parsing\DFADefinitionBase.cs" />
78 <Compile Include="Parsing\DFAStateDescriptor.cs" />
80 <Compile Include="Parsing\DFAStateDescriptor.cs" />
79 <Compile Include="Parsing\DFAutomaton.cs" />
81 <Compile Include="Parsing\DFAutomaton.cs" />
80 <Compile Include="Parsing\EDFADefinition.cs" />
82 <Compile Include="Parsing\EDFADefinition.cs" />
81 <Compile Include="Parsing\EmptyToken.cs" />
83 <Compile Include="Parsing\EmptyToken.cs" />
82 <Compile Include="Parsing\EndToken.cs" />
84 <Compile Include="Parsing\EndToken.cs" />
83 <Compile Include="Parsing\EnumAlphabet.cs" />
85 <Compile Include="Parsing\EnumAlphabet.cs" />
84 <Compile Include="Parsing\Grammar.cs" />
86 <Compile Include="Parsing\Grammar.cs" />
85 <Compile Include="Parsing\IAlphabet.cs" />
87 <Compile Include="Parsing\IAlphabet.cs" />
86 <Compile Include="Parsing\IDFADefinition.cs" />
88 <Compile Include="Parsing\IDFADefinition.cs" />
87 <Compile Include="Parsing\IVisitor.cs" />
89 <Compile Include="Parsing\IVisitor.cs" />
88 <Compile Include="Parsing\ParserException.cs" />
90 <Compile Include="Parsing\ParserException.cs" />
89 <Compile Include="Parsing\Scanner.cs" />
91 <Compile Include="Parsing\Scanner.cs" />
90 <Compile Include="Parsing\StarToken.cs" />
92 <Compile Include="Parsing\StarToken.cs" />
91 <Compile Include="Parsing\SymbolToken.cs" />
93 <Compile Include="Parsing\SymbolToken.cs" />
92 <Compile Include="Parsing\Token.cs" />
94 <Compile Include="Parsing\Token.cs" />
93 <Compile Include="SafePool.cs" />
95 <Compile Include="SafePool.cs" />
94 <Compile Include="ServiceLocator.cs" />
96 <Compile Include="ServiceLocator.cs" />
95 <Compile Include="TaskController.cs" />
97 <Compile Include="TaskController.cs" />
96 <Compile Include="ProgressInitEventArgs.cs" />
98 <Compile Include="ProgressInitEventArgs.cs" />
97 <Compile Include="Properties\AssemblyInfo.cs" />
99 <Compile Include="Properties\AssemblyInfo.cs" />
98 <Compile Include="Promise.cs" />
100 <Compile Include="Promise.cs" />
99 <Compile Include="Parallels\AsyncPool.cs" />
101 <Compile Include="Parallels\AsyncPool.cs" />
100 <Compile Include="Safe.cs" />
102 <Compile Include="Safe.cs" />
101 <Compile Include="ValueEventArgs.cs" />
103 <Compile Include="ValueEventArgs.cs" />
104 <Compile Include="PromiseExtensions.cs" />
105 <Compile Include="TransientPromiseException.cs" />
106 <Compile Include="SyncContextPromise.cs" />
102 </ItemGroup>
107 </ItemGroup>
103 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
108 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
104 <ItemGroup />
109 <ItemGroup />
110 <ProjectExtensions>
111 <MonoDevelop>
112 <Properties>
113 <Policies>
114 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
115 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
116 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
117 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
118 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
119 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
120 <NameConventionPolicy>
121 <Rules>
122 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
123 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
124 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
125 <RequiredPrefixes>
126 <String>I</String>
127 </RequiredPrefixes>
128 </NamingRule>
129 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
130 <RequiredSuffixes>
131 <String>Attribute</String>
132 </RequiredSuffixes>
133 </NamingRule>
134 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
135 <RequiredSuffixes>
136 <String>EventArgs</String>
137 </RequiredSuffixes>
138 </NamingRule>
139 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
140 <RequiredSuffixes>
141 <String>Exception</String>
142 </RequiredSuffixes>
143 </NamingRule>
144 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
145 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
146 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
147 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
148 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
149 <RequiredPrefixes>
150 <String>m_</String>
151 </RequiredPrefixes>
152 </NamingRule>
153 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
154 <RequiredPrefixes>
155 <String>_</String>
156 </RequiredPrefixes>
157 </NamingRule>
158 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
159 <RequiredPrefixes>
160 <String>m_</String>
161 </RequiredPrefixes>
162 </NamingRule>
163 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
164 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
165 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
166 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
167 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
168 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
169 <RequiredPrefixes>
170 <String>T</String>
171 </RequiredPrefixes>
172 </NamingRule>
173 </Rules>
174 </NameConventionPolicy>
175 </Policies>
176 </Properties>
177 </MonoDevelop>
178 </ProjectExtensions>
105 </Project> No newline at end of file
179 </Project>
@@ -1,113 +1,103
1 using Implab.Parsing;
1 using Implab.Parsing;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6 using System.Threading.Tasks;
6 using System.Threading.Tasks;
7
7
8 namespace Implab.JSON {
8 namespace Implab.JSON {
9 internal class JSONGrammar : Grammar<JSONGrammar> {
9 internal class JSONGrammar : Grammar<JSONGrammar> {
10 public enum TokenType : int{
10 public enum TokenType : int {
11 None,
11 None,
12 BeginObject,
12 BeginObject,
13 EndObject,
13 EndObject,
14 BeginArray,
14 BeginArray,
15 EndArray,
15 EndArray,
16 String,
16 String,
17 Number,
17 Number,
18 Literal,
18 Literal,
19 NameSeparator,
19 NameSeparator,
20 ValueSeparator,
20 ValueSeparator,
21
21
22 StringBound,
22 StringBound,
23 EscapedChar,
23 EscapedChar,
24 UnescapedChar,
24 UnescapedChar,
25 EscapedUnicode,
25 EscapedUnicode,
26
26
27 Minus,
27 Minus,
28 Plus,
28 Plus,
29 Sign,
29 Sign,
30 Integer,
30 Integer,
31 Dot,
31 Dot,
32 Exp
32 Exp
33 }
33 }
34
34
35 readonly CDFADefinition m_jsonDFA;
35 readonly CDFADefinition m_jsonDFA;
36 readonly CDFADefinition m_stringDFA;
36 readonly CDFADefinition m_stringDFA;
37
37
38 public JSONGrammar() {
38 public JSONGrammar() {
39 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
39 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
40 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
40 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
41 var digit9 = SymbolRangeToken('1', '9');
41 var digit9 = SymbolRangeToken('1', '9');
42 var zero = SymbolToken('0');
42 var zero = SymbolToken('0');
43 var digit = zero.Or(digit9);
43 var digit = zero.Or(digit9);
44 var dot = SymbolToken('.');
44 var dot = SymbolToken('.');
45 var minus = SymbolToken('-');
45 var minus = SymbolToken('-');
46 var sign = SymbolSetToken('-', '+');
46 var sign = SymbolSetToken('-', '+');
47 var expSign = SymbolSetToken('e', 'E');
47 var expSign = SymbolSetToken('e', 'E');
48 var letters = SymbolRangeToken('a', 'z');
48 var letters = SymbolRangeToken('a', 'z');
49 var integer = zero.Or(digit9.Cat(digit.EClosure()));
49 var integer = zero.Or(digit9.Cat(digit.EClosure()));
50 var frac = dot.Cat(digit.Closure());
50 var frac = dot.Cat(digit.Closure());
51 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
51 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
52 var quote = SymbolToken('"');
52 var quote = SymbolToken('"');
53 var backSlash = SymbolToken('\\');
53 var backSlash = SymbolToken('\\');
54 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
54 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
55 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
55 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
56 var escape = backSlash.Cat(specialEscapeChars.Or(unicodeEspace));
57 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
56 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
58 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
57 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
59 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
58 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
60 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
59 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
61 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
60 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
62 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
61 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
63 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
62 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
64
63
65 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
64 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
66 var literal = letters.Closure();
65 var literal = letters.Closure();
67 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
66 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
68 var character = unescaped.Or(escape);
69 var str = quote.Cat(character.EClosure()).Cat(quote);
70
71
67
72 var jsonExpression =
68 var jsonExpression =
73 number.Tag(TokenType.Number)
69 number.Tag(TokenType.Number)
74 .Or(literal.Tag(TokenType.Literal))
70 .Or(literal.Tag(TokenType.Literal))
75 .Or(quote.Tag(TokenType.StringBound))
71 .Or(quote.Tag(TokenType.StringBound))
76 .Or(beginObject.Tag(TokenType.BeginObject))
72 .Or(beginObject.Tag(TokenType.BeginObject))
77 .Or(endObject.Tag(TokenType.EndObject))
73 .Or(endObject.Tag(TokenType.EndObject))
78 .Or(beginArray.Tag(TokenType.BeginArray))
74 .Or(beginArray.Tag(TokenType.BeginArray))
79 .Or(endArray.Tag(TokenType.EndArray))
75 .Or(endArray.Tag(TokenType.EndArray))
80 .Or(nameSep.Tag(TokenType.NameSeparator))
76 .Or(nameSep.Tag(TokenType.NameSeparator))
81 .Or(valueSep.Tag(TokenType.ValueSeparator));
77 .Or(valueSep.Tag(TokenType.ValueSeparator));
82
78
83
79
84 var jsonStringExpression =
80 var jsonStringExpression =
85 quote.Tag(TokenType.StringBound)
81 quote.Tag(TokenType.StringBound)
86 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
82 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
87 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
83 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
88 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
84 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
89
85
90 var jsonNumberExpression =
91 minus.Tag(TokenType.Minus)
92 .Or(SymbolToken('+').Tag(TokenType.Plus))
93 .Or(digit.Closure().Tag(TokenType.Integer))
94 .Or(dot.Tag(TokenType.Dot))
95 .Or(expSign.Tag(TokenType.Exp));
96
86
97 m_jsonDFA = BuildDFA(jsonExpression);
87 m_jsonDFA = BuildDFA(jsonExpression);
98 m_stringDFA = BuildDFA(jsonStringExpression);
88 m_stringDFA = BuildDFA(jsonStringExpression);
99 }
89 }
100
90
101 public CDFADefinition JsonDFA {
91 public CDFADefinition JsonDFA {
102 get {
92 get {
103 return m_jsonDFA;
93 return m_jsonDFA;
104 }
94 }
105 }
95 }
106
96
107 public CDFADefinition JsonStringDFA {
97 public CDFADefinition JsonStringDFA {
108 get {
98 get {
109 return m_stringDFA;
99 return m_stringDFA;
110 }
100 }
111 }
101 }
112 }
102 }
113 }
103 }
@@ -1,227 +1,256
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.IO;
3 using System.IO;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6 using System.Threading.Tasks;
6 using System.Threading.Tasks;
7
7
8 namespace Implab.JSON {
8 namespace Implab.JSON {
9 public class JSONWriter {
9 public class JSONWriter {
10 struct Context {
10 struct Context {
11 public bool needComma;
11 public bool needComma;
12 public JSONElementContext element;
12 public JSONElementContext element;
13 }
13 }
14 Stack<Context> m_contextStack = new Stack<Context>();
14 Stack<Context> m_contextStack = new Stack<Context>();
15 Context m_context;
15 Context m_context;
16
16
17 TextWriter m_writer;
17 TextWriter m_writer;
18 bool m_indent;
18 readonly bool m_indent = true;
19 readonly int m_indentSize = 4;
19
20
20 static readonly char [] _escapeBKS,
21 static readonly char [] _escapeBKS,
21 _escapeFWD,
22 _escapeFWD,
22 _escapeCR,
23 _escapeCR,
23 _escapeNL,
24 _escapeNL,
24 _escapeTAB,
25 _escapeTAB,
25 _escapeSLASH,
26 _escapeSLASH,
26 _escapeBSLASH,
27 _escapeBSLASH,
27 _escapeQ;
28 _escapeQ;
28
29
29 static JSONWriter() {
30 static JSONWriter() {
30 _escapeBKS = "\\b".ToCharArray();
31 _escapeBKS = "\\b".ToCharArray();
31 _escapeFWD = "\\f".ToCharArray();
32 _escapeFWD = "\\f".ToCharArray();
32 _escapeCR = "\\r".ToCharArray();
33 _escapeCR = "\\r".ToCharArray();
33 _escapeNL = "\\n".ToCharArray();
34 _escapeNL = "\\n".ToCharArray();
34 _escapeTAB = "\\t".ToCharArray();
35 _escapeTAB = "\\t".ToCharArray();
35 _escapeBSLASH = "\\\\".ToCharArray();
36 _escapeBSLASH = "\\\\".ToCharArray();
36 _escapeSLASH = "\\/".ToCharArray();
37 _escapeSLASH = "\\/".ToCharArray();
37 _escapeQ = "\\\"".ToCharArray();
38 _escapeQ = "\\\"".ToCharArray();
38 }
39 }
39
40
40 public JSONWriter(TextWriter writer) {
41 public JSONWriter(TextWriter writer) {
41 Safe.ArgumentNotNull(writer, "writer");
42 Safe.ArgumentNotNull(writer, "writer");
42
43
43 m_writer = writer;
44 m_writer = writer;
44 }
45 }
45
46
47 public JSONWriter(TextWriter writer, bool indent) {
48 Safe.ArgumentNotNull(writer, "writer");
49
50 m_writer = writer;
51 m_indent = indent;
52 }
53
54 void WriteIndent() {
55 if (m_indent) {
56 var indent = new char[m_contextStack.Count * m_indentSize + 1];
57 indent[0] = '\n';
58 for (int i = 1; i < indent.Length; i++)
59 indent[i] = ' ';
60 m_writer.Write(new String(indent));
61 } else {
62 m_writer.Write(' ');
63 }
64 }
65
46 void WriteMemberName(string name) {
66 void WriteMemberName(string name) {
47 Safe.ArgumentNotEmpty(name, "name");
67 Safe.ArgumentNotEmpty(name, "name");
48 if (m_context.element != JSONElementContext.Object)
68 if (m_context.element != JSONElementContext.Object)
49 OperationNotApplicable("WriteMember");
69 OperationNotApplicable("WriteMember");
50 if (m_context.needComma)
70 if (m_context.needComma)
51 m_writer.Write(", ");
71 m_writer.Write(",");
52 // TODO indent
72
73 WriteIndent();
53 m_context.needComma = true;
74 m_context.needComma = true;
54 Write(name);
75 Write(name);
55 m_writer.Write(" : ");
76 m_writer.Write(" : ");
56 }
77 }
57
78
58 public void WriteValue(string name, string value) {
79 public void WriteValue(string name, string value) {
59 WriteMemberName(name);
80 WriteMemberName(name);
60 Write(value);
81 Write(value);
61 }
82 }
62
83
63 public void WriteValue(string name, bool value) {
84 public void WriteValue(string name, bool value) {
64 WriteMemberName(name);
85 WriteMemberName(name);
65 Write(value);
86 Write(value);
66 }
87 }
67
88
68 public void WriteValue(string name, double value) {
89 public void WriteValue(string name, double value) {
69 WriteMemberName(name);
90 WriteMemberName(name);
70 Write(value);
91 Write(value);
71 }
92 }
72
93
73
74
75 public void WriteValue(string value) {
94 public void WriteValue(string value) {
76 if (m_context.element != JSONElementContext.Array)
95 if (m_context.element != JSONElementContext.Array)
77 OperationNotApplicable("WriteValue");
96 OperationNotApplicable("WriteValue");
78 if (m_context.needComma)
97 if (m_context.needComma)
79 m_writer.Write(", ");
98 m_writer.Write(",");
99 WriteIndent();
80 m_context.needComma = true;
100 m_context.needComma = true;
81
101
82 Write(value);
102 Write(value);
83 }
103 }
84
104
85 public void WriteValue(bool value) {
105 public void WriteValue(bool value) {
86 if (m_context.element != JSONElementContext.Array)
106 if (m_context.element != JSONElementContext.Array)
87 OperationNotApplicable("WriteValue");
107 OperationNotApplicable("WriteValue");
88 if (m_context.needComma)
108 if (m_context.needComma)
89 m_writer.Write(", ");
109 m_writer.Write(",");
90 m_context.needComma = true;
110 m_context.needComma = true;
91
111
112 WriteIndent();
92 Write(value);
113 Write(value);
93 }
114 }
94
115
95 public void WriteValue(double value) {
116 public void WriteValue(double value) {
96 if (m_context.element != JSONElementContext.Array)
117 if (m_context.element != JSONElementContext.Array)
97 OperationNotApplicable("WriteValue");
118 OperationNotApplicable("WriteValue");
98 if (m_context.needComma)
119 if (m_context.needComma)
99 m_writer.Write(", ");
120 m_writer.Write(",");
100 m_context.needComma = true;
121 m_context.needComma = true;
101
122
123 WriteIndent();
102 Write(value);
124 Write(value);
103 }
125 }
104
126
105 public void BeginObject() {
127 public void BeginObject() {
106 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
128 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
107 OperationNotApplicable("BeginObject");
129 OperationNotApplicable("BeginObject");
108 if (m_context.needComma)
130 if (m_context.needComma)
109 m_writer.Write(", ");
131 m_writer.Write(",");
132
133 WriteIndent();
134
110 m_context.needComma = true;
135 m_context.needComma = true;
111
136
112 m_contextStack.Push(m_context);
137 m_contextStack.Push(m_context);
113
138
114 m_context = new Context { element = JSONElementContext.Object, needComma = false };
139 m_context = new Context { element = JSONElementContext.Object, needComma = false };
115 m_writer.Write("{ ");
140 m_writer.Write("{");
116 }
141 }
117
142
118 public void BeginObject(string name) {
143 public void BeginObject(string name) {
119 WriteMemberName(name);
144 WriteMemberName(name);
120
145
121 m_contextStack.Push(m_context);
146 m_contextStack.Push(m_context);
122
147
123 m_context = new Context { element = JSONElementContext.Object, needComma = false };
148 m_context = new Context { element = JSONElementContext.Object, needComma = false };
124 m_writer.Write("{ ");
149 m_writer.Write("{");
125 }
150 }
126
151
127 public void EndObject() {
152 public void EndObject() {
128 if (m_context.element != JSONElementContext.Object)
153 if (m_context.element != JSONElementContext.Object)
129 OperationNotApplicable("EndArray");
154 OperationNotApplicable("EndArray");
130
155
131 m_writer.Write(" }");
132 m_context = m_contextStack.Pop();
156 m_context = m_contextStack.Pop();
157 WriteIndent();
158 m_writer.Write("}");
133 }
159 }
134
160
135 public void BeginArray() {
161 public void BeginArray() {
136 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
162 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
137 throw new InvalidOperationException();
163 throw new InvalidOperationException();
138 if (m_context.needComma)
164 if (m_context.needComma) {
139 m_writer.Write(", ");
165 m_writer.Write(",");
166
167 }
140 m_context.needComma = true;
168 m_context.needComma = true;
141
169
170 WriteIndent();
142 m_contextStack.Push(m_context);
171 m_contextStack.Push(m_context);
143
144 m_context = new Context { element = JSONElementContext.Array, needComma = false };
172 m_context = new Context { element = JSONElementContext.Array, needComma = false };
145 m_writer.Write("[ ");
173 m_writer.Write("[");
146 }
174 }
147
175
148 public void BeginArray(string name) {
176 public void BeginArray(string name) {
149 WriteMemberName(name);
177 WriteMemberName(name);
150
178
151 m_contextStack.Push(m_context);
179 m_contextStack.Push(m_context);
152
180
153 m_context = new Context { element = JSONElementContext.Array, needComma = false };
181 m_context = new Context { element = JSONElementContext.Array, needComma = false };
154 m_writer.Write("[ ");
182 m_writer.Write("[");
155 }
183 }
156
184
157 public void EndArray() {
185 public void EndArray() {
158 if (m_context.element != JSONElementContext.Array)
186 if (m_context.element != JSONElementContext.Array)
159 OperationNotApplicable("EndArray");
187 OperationNotApplicable("EndArray");
160
188
161 m_writer.Write(" ]");
162 m_context = m_contextStack.Pop();
189 m_context = m_contextStack.Pop();
190 WriteIndent();
191 m_writer.Write("]");
163 }
192 }
164
193
165 void Write(bool value) {
194 void Write(bool value) {
166 m_writer.Write(value ? "true" : "false");
195 m_writer.Write(value ? "true" : "false");
167 }
196 }
168
197
169
198
170 void Write(string value) {
199 void Write(string value) {
171 if (value == null)
200 if (value == null)
172 m_writer.Write("null");
201 m_writer.Write("null");
173
202
174 var chars = value.ToCharArray();
203 var chars = value.ToCharArray();
175 m_writer.Write('"');
204 m_writer.Write('"');
176
205
177 for (int i = 0; i < chars.Length; i++) {
206 for (int i = 0; i < chars.Length; i++) {
178 var ch = chars[i];
207 var ch = chars[i];
179
208
180 switch (ch) {
209 switch (ch) {
181 case '\b':
210 case '\b':
182 m_writer.Write(_escapeBKS);
211 m_writer.Write(_escapeBKS);
183 break;
212 break;
184 case '\f':
213 case '\f':
185 m_writer.Write(_escapeFWD);
214 m_writer.Write(_escapeFWD);
186 break;
215 break;
187 case '\r':
216 case '\r':
188 m_writer.Write(_escapeCR);
217 m_writer.Write(_escapeCR);
189 break;
218 break;
190 case '\n':
219 case '\n':
191 m_writer.Write(_escapeNL);
220 m_writer.Write(_escapeNL);
192 break;
221 break;
193 case '\t':
222 case '\t':
194 m_writer.Write(_escapeTAB);
223 m_writer.Write(_escapeTAB);
195 break;
224 break;
196 case '\\':
225 case '\\':
197 m_writer.Write(_escapeBSLASH);
226 m_writer.Write(_escapeBSLASH);
198 break;
227 break;
199 case '/':
228 case '/':
200 m_writer.Write(_escapeSLASH);
229 m_writer.Write(_escapeSLASH);
201 break;
230 break;
202 case '"':
231 case '"':
203 m_writer.Write(_escapeQ);
232 m_writer.Write(_escapeQ);
204 break;
233 break;
205 default:
234 default:
206 if (ch < 0x20) {
235 if (ch < 0x20) {
207 m_writer.Write("\\u00{0:x2}",(int)ch);
236 m_writer.Write("\\u00{0:x2}",(int)ch);
208 } else {
237 } else {
209 m_writer.Write(ch);
238 m_writer.Write(ch);
210 }
239 }
211 break;
240 break;
212 }
241 }
213 }
242 }
214
243
215 m_writer.Write('"');
244 m_writer.Write('"');
216 }
245 }
217
246
218 void Write(double value) {
247 void Write(double value) {
219 m_writer.Write(value);
248 m_writer.Write(value);
220 }
249 }
221
250
222 void OperationNotApplicable(string opName) {
251 void OperationNotApplicable(string opName) {
223 throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
252 throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
224 }
253 }
225
254
226 }
255 }
227 }
256 }
@@ -1,191 +1,194
1 using Implab.Diagnostics;
1 using Implab.Diagnostics;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6 using System.Text;
6 using System.Text;
7 using System.Threading;
7 using System.Threading;
8
8
9 namespace Implab.Parallels {
9 namespace Implab.Parallels {
10 public static class ArrayTraits {
10 public static class ArrayTraits {
11 class ArrayIterator<TSrc> : DispatchPool<int> {
11 class ArrayIterator<TSrc> : DispatchPool<int> {
12 readonly Action<TSrc> m_action;
12 readonly Action<TSrc> m_action;
13 readonly TSrc[] m_source;
13 readonly TSrc[] m_source;
14 readonly Promise<int> m_promise = new Promise<int>();
14 readonly Promise<int> m_promise = new Promise<int>();
15 readonly TraceContext m_traceContext;
15 readonly TraceContext m_traceContext;
16
16
17 int m_pending;
17 int m_pending;
18 int m_next;
18 int m_next;
19
19
20 public ArrayIterator(TSrc[] source, Action<TSrc> action, int threads)
20 public ArrayIterator(TSrc[] source, Action<TSrc> action, int threads)
21 : base(threads) {
21 : base(threads) {
22
22
23 Debug.Assert(source != null);
23 Debug.Assert(source != null);
24 Debug.Assert(action != null);
24 Debug.Assert(action != null);
25
25
26 m_traceContext = TraceContext.Snapshot();
26 m_traceContext = TraceContext.Snapshot();
27 m_next = 0;
27 m_next = 0;
28 m_source = source;
28 m_source = source;
29 m_pending = source.Length;
29 m_pending = source.Length;
30 m_action = action;
30 m_action = action;
31
31
32 m_promise.Anyway(() => Dispose());
32 m_promise.Anyway(() => Dispose());
33 m_promise.Cancelled(() => Dispose());
33 m_promise.Cancelled(() => Dispose());
34
34
35 InitPool();
35 InitPool();
36 }
36 }
37
37
38 public Promise<int> Promise {
38 public Promise<int> Promise {
39 get {
39 get {
40 return m_promise;
40 return m_promise;
41 }
41 }
42 }
42 }
43
43
44 protected override void Worker() {
44 protected override void Worker() {
45 TraceContext.Fork(m_traceContext);
45 TraceContext.Fork(m_traceContext);
46 base.Worker();
46 base.Worker();
47 }
47 }
48
48
49 protected override bool TryDequeue(out int unit) {
49 protected override bool TryDequeue(out int unit) {
50 unit = Interlocked.Increment(ref m_next) - 1;
50 unit = Interlocked.Increment(ref m_next) - 1;
51 return unit >= m_source.Length ? false : true;
51 return unit >= m_source.Length ? false : true;
52 }
52 }
53
53
54 protected override void InvokeUnit(int unit) {
54 protected override void InvokeUnit(int unit) {
55 try {
55 try {
56 m_action(m_source[unit]);
56 m_action(m_source[unit]);
57 var pending = Interlocked.Decrement(ref m_pending);
57 var pending = Interlocked.Decrement(ref m_pending);
58 if (pending == 0)
58 if (pending == 0)
59 m_promise.Resolve(m_source.Length);
59 m_promise.Resolve(m_source.Length);
60 } catch (Exception e) {
60 } catch (Exception e) {
61 m_promise.Reject(e);
61 m_promise.Reject(e);
62 }
62 }
63 }
63 }
64 }
64 }
65
65
66 class ArrayMapper<TSrc, TDst>: DispatchPool<int> {
66 class ArrayMapper<TSrc, TDst>: DispatchPool<int> {
67 readonly Func<TSrc, TDst> m_transform;
67 readonly Func<TSrc, TDst> m_transform;
68 readonly TSrc[] m_source;
68 readonly TSrc[] m_source;
69 readonly TDst[] m_dest;
69 readonly TDst[] m_dest;
70 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
70 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
71 readonly TraceContext m_traceContext;
71 readonly TraceContext m_traceContext;
72
72
73 int m_pending;
73 int m_pending;
74 int m_next;
74 int m_next;
75
75
76 public ArrayMapper(TSrc[] source, Func<TSrc, TDst> transform, int threads)
76 public ArrayMapper(TSrc[] source, Func<TSrc, TDst> transform, int threads)
77 : base(threads) {
77 : base(threads) {
78
78
79 Debug.Assert (source != null);
79 Debug.Assert (source != null);
80 Debug.Assert( transform != null);
80 Debug.Assert( transform != null);
81
81
82 m_next = 0;
82 m_next = 0;
83 m_source = source;
83 m_source = source;
84 m_dest = new TDst[source.Length];
84 m_dest = new TDst[source.Length];
85 m_pending = source.Length;
85 m_pending = source.Length;
86 m_transform = transform;
86 m_transform = transform;
87 m_traceContext = TraceContext.Snapshot();
87 m_traceContext = TraceContext.Snapshot();
88
88
89 m_promise.Anyway(() => Dispose());
89 m_promise.Anyway(() => Dispose());
90 m_promise.Cancelled(() => Dispose());
90 m_promise.Cancelled(() => Dispose());
91
91
92 InitPool();
92 InitPool();
93 }
93 }
94
94
95 public Promise<TDst[]> Promise {
95 public Promise<TDst[]> Promise {
96 get {
96 get {
97 return m_promise;
97 return m_promise;
98 }
98 }
99 }
99 }
100
100
101 protected override void Worker() {
101 protected override void Worker() {
102 TraceContext.Fork(m_traceContext);
102 TraceContext.Fork(m_traceContext);
103 base.Worker();
103 base.Worker();
104 }
104 }
105
105
106 protected override bool TryDequeue(out int unit) {
106 protected override bool TryDequeue(out int unit) {
107 unit = Interlocked.Increment(ref m_next) - 1;
107 unit = Interlocked.Increment(ref m_next) - 1;
108 return unit >= m_source.Length ? false : true;
108 return unit >= m_source.Length ? false : true;
109 }
109 }
110
110
111 protected override void InvokeUnit(int unit) {
111 protected override void InvokeUnit(int unit) {
112 try {
112 try {
113 m_dest[unit] = m_transform(m_source[unit]);
113 m_dest[unit] = m_transform(m_source[unit]);
114 var pending = Interlocked.Decrement(ref m_pending);
114 var pending = Interlocked.Decrement(ref m_pending);
115 if (pending == 0)
115 if (pending == 0)
116 m_promise.Resolve(m_dest);
116 m_promise.Resolve(m_dest);
117 } catch (Exception e) {
117 } catch (Exception e) {
118 m_promise.Reject(e);
118 m_promise.Reject(e);
119 }
119 }
120 }
120 }
121 }
121 }
122
122
123 public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) {
123 public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) {
124 if (source == null)
124 if (source == null)
125 throw new ArgumentNullException("source");
125 throw new ArgumentNullException("source");
126 if (transform == null)
126 if (transform == null)
127 throw new ArgumentNullException("transform");
127 throw new ArgumentNullException("transform");
128
128
129 var mapper = new ArrayMapper<TSrc, TDst>(source, transform, threads);
129 var mapper = new ArrayMapper<TSrc, TDst>(source, transform, threads);
130 return mapper.Promise;
130 return mapper.Promise;
131 }
131 }
132
132
133 public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) {
133 public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) {
134 if (source == null)
134 if (source == null)
135 throw new ArgumentNullException("source");
135 throw new ArgumentNullException("source");
136 if (action == null)
136 if (action == null)
137 throw new ArgumentNullException("action");
137 throw new ArgumentNullException("action");
138
138
139 var iter = new ArrayIterator<TSrc>(source, action, threads);
139 var iter = new ArrayIterator<TSrc>(source, action, threads);
140 return iter.Promise;
140 return iter.Promise;
141 }
141 }
142
142
143 public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, ChainedOperation<TSrc, TDst> transform, int threads) {
143 public static IPromise<TDst[]> ChainedMap<TSrc, TDst>(this TSrc[] source, ChainedOperation<TSrc, TDst> transform, int threads) {
144 if (source == null)
144 if (source == null)
145 throw new ArgumentNullException("source");
145 throw new ArgumentNullException("source");
146 if (transform == null)
146 if (transform == null)
147 throw new ArgumentNullException("transform");
147 throw new ArgumentNullException("transform");
148 if (threads <= 0)
148 if (threads <= 0)
149 throw new ArgumentOutOfRangeException("Threads number must be greater then zero");
149 throw new ArgumentOutOfRangeException("Threads number must be greater then zero");
150
150
151 if (source.Length == 0)
151 if (source.Length == 0)
152 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
152 return Promise<TDst[]>.ResultToPromise(new TDst[0]);
153
153
154 var promise = new Promise<TDst[]>();
154 var promise = new Promise<TDst[]>();
155 var res = new TDst[source.Length];
155 var res = new TDst[source.Length];
156 var pending = source.Length;
156 var pending = source.Length;
157
157
158 var semaphore = new Semaphore(threads, threads);
158 var semaphore = new Semaphore(threads, threads);
159
159
160 AsyncPool.InvokeNewThread(() => {
160 AsyncPool.InvokeNewThread(() => {
161 for (int i = 0; i < source.Length; i++) {
161 for (int i = 0; i < source.Length; i++) {
162 if(promise.IsResolved)
162 if(promise.IsResolved)
163 break; // stop processing in case of error or cancellation
163 break; // stop processing in case of error or cancellation
164 var idx = i;
164 var idx = i;
165 semaphore.WaitOne();
165 semaphore.WaitOne();
166 try {
166 try {
167 var p1 = transform(source[i]);
167 var p1 = transform(source[i]);
168 p1.Anyway(() => semaphore.Release());
168 p1.Anyway(() => semaphore.Release());
169 p1.Cancelled(() => semaphore.Release());
169 p1.Cancelled(() => semaphore.Release());
170 p1.Then(
170 p1.Then(
171 x => {
171 x => {
172 res[idx] = x;
172 res[idx] = x;
173 var left = Interlocked.Decrement(ref pending);
173 var left = Interlocked.Decrement(ref pending);
174 if (left == 0)
174 if (left == 0)
175 promise.Resolve(res);
175 promise.Resolve(res);
176 },
176 },
177 e => promise.Reject(e)
177 e => {
178 promise.Reject(e);
179 throw new TransientPromiseException(e);
180 }
178 );
181 );
179
182
180 } catch (Exception e) {
183 } catch (Exception e) {
181 promise.Reject(e);
184 promise.Reject(e);
182 }
185 }
183 }
186 }
184 return 0;
187 return 0;
185 });
188 });
186
189
187 return promise.Anyway(() => semaphore.Dispose());
190 return promise.Anyway(() => semaphore.Dispose());
188 }
191 }
189
192
190 }
193 }
191 }
194 }
@@ -1,762 +1,731
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Reflection;
3 using System.Reflection;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Threading;
5 using System.Threading;
6 using Implab.Parallels;
6 using Implab.Parallels;
7
7
8 namespace Implab {
8 namespace Implab {
9
9
10 public delegate void ErrorHandler(Exception e);
10 public delegate void ErrorHandler(Exception e);
11 public delegate T ErrorHandler<out T>(Exception e);
11 public delegate T ErrorHandler<out T>(Exception e);
12 public delegate void ResultHandler<in T>(T result);
12 public delegate void ResultHandler<in T>(T result);
13 public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result);
13 public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result);
14 public delegate IPromise<TNew> ChainedOperation<in TSrc, TNew>(TSrc result);
14 public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result);
15
15
16 /// <summary>
16 /// <summary>
17 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
17 /// Класс для асинхронного получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². Π’Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ΅ "ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅".
18 /// </summary>
18 /// </summary>
19 /// <typeparam name="T">Π’ΠΈΠΏ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°</typeparam>
19 /// <typeparam name="T">Π’ΠΈΠΏ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°</typeparam>
20 /// <remarks>
20 /// <remarks>
21 /// <para>БСрвис ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π΄Π°Π΅Ρ‚ ΠΎΠ±Π΅Ρ‰Π°ΠΈΠ½ΠΈΠ΅ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ,
21 /// <para>БСрвис ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ Π΄Π°Π΅Ρ‚ ΠΎΠ±Π΅Ρ‰Π°ΠΈΠ½ΠΈΠ΅ ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ,
22 /// ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ² Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ряд ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎ для получСния
22 /// ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ² Ρ‚Π°ΠΊΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ряд ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎ для получСния
23 /// событий выполнСния обСщания, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ прСдоставлСнии Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².</para>
23 /// событий выполнСния обСщания, Ρ‚ΠΎΠ΅ΡΡ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈ прСдоставлСнии Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ².</para>
24 /// <para>
24 /// <para>
25 /// ΠžΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ с ошибкой. Для подписки Π½Π°
25 /// ΠžΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚Π°ΠΊ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ с ошибкой. Для подписки Π½Π°
26 /// Π΄Π°Π½Π½Ρ‹Π΅ события ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Then</c>.
26 /// Π΄Π°Π½Π½Ρ‹Π΅ события ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Then</c>.
27 /// </para>
27 /// </para>
28 /// <para>
28 /// <para>
29 /// БСрвис, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ошибкой),
29 /// БСрвис, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ошибкой),
30 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Resolve</c> Π»ΠΈΠ±ΠΎ <c>Reject</c> для оповСщСния ΠΊΠ»ΠΈΠ΅Ρ‚Π½Π° ΠΎ
30 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ <c>Resolve</c> Π»ΠΈΠ±ΠΎ <c>Reject</c> для оповСщСния ΠΊΠ»ΠΈΠ΅Ρ‚Π½Π° ΠΎ
31 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ обСщания.
31 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ обСщания.
32 /// </para>
32 /// </para>
33 /// <para>
33 /// <para>
34 /// Если сСрвСр успСл Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° Π½Π΅Π³ΠΎ подписался,
34 /// Если сСрвСр успСл Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° Π½Π΅Π³ΠΎ подписался,
35 /// Ρ‚ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ подписки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠ΅ события Π² синхронном
35 /// Ρ‚ΠΎ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ подписки ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰ΠΈΠ΅ события Π² синхронном
36 /// Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ Π² любом случаС. Π˜Π½Π°Ρ‡Π΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²
36 /// Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ Π² любом случаС. Π˜Π½Π°Ρ‡Π΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ Π²
37 /// список Π² порядкС подписания ΠΈ Π² этом ΠΆΠ΅ порядкС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ
37 /// список Π² порядкС подписания ΠΈ Π² этом ΠΆΠ΅ порядкС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ
38 /// обСщания.
38 /// обСщания.
39 /// </para>
39 /// </para>
40 /// <para>
40 /// <para>
41 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обСщания ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
41 /// ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обСщания ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
42 /// связанныС асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ обСщания. Для этого слСдуСт
42 /// связанныС асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ обСщания. Для этого слСдуСт
43 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ <c>Then</c>.
43 /// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ <c>Then</c>.
44 /// </para>
44 /// </para>
45 /// <para>
45 /// <para>
46 /// Π’Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ <c>Resolve</c> ΠΈ <c>Reject</c> Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
46 /// Π’Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ <c>Resolve</c> ΠΈ <c>Reject</c> Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
47 /// Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΎΡ€ обСщания ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ противорСчия.
47 /// Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Ρ‚ΠΎΡ€ обСщания ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ противорСчия.
48 /// </para>
48 /// </para>
49 /// </remarks>
49 /// </remarks>
50 public class Promise<T> : IPromise<T> {
50 public class Promise<T> : IPromise<T> {
51
51
52 protected struct HandlerDescriptor {
52 protected struct HandlerDescriptor {
53 public ResultHandler<T> resultHandler;
53 public ResultHandler<T> resultHandler;
54 public ErrorHandler errorHandler;
54 public ErrorHandler<T> errorHandler;
55 public Action cancellHandler;
55 public Action cancellHandler;
56 public Promise<T> medium;
56
57
57 public void Resolve(T result) {
58 public void Resolve(T result) {
58 if (resultHandler != null)
59 if (resultHandler != null) {
59 try {
60 try {
60 resultHandler(result);
61 resultHandler(result);
61 } catch (Exception e) {
62 } catch (Exception e) {
62 Reject(e);
63 Reject(e);
64 return;
63 }
65 }
66 }
67 if (medium != null)
68 medium.Resolve(result);
64 }
69 }
65
70
66 public void Reject(Exception err) {
71 public void Reject(Exception err) {
67 if (errorHandler != null)
72 if (errorHandler != null) {
68 try {
73 try {
69 errorHandler(err);
74 var res = errorHandler(err);
70 } catch {
75 if (medium != null)
76 medium.Resolve(res);
77 } catch (TransientPromiseException err2) {
78 if (medium != null)
79 medium.Reject(err2.InnerException);
80 } catch (Exception err2) {
81 if (medium != null)
82 medium.Reject(err2);
71 }
83 }
84 } else if (medium != null)
85 medium.Reject(err);
72 }
86 }
73
87
74 public void Cancel() {
88 public void Cancel() {
75 if (cancellHandler != null)
89 if (cancellHandler != null) {
76 try {
90 try {
77 cancellHandler();
91 cancellHandler();
78 } catch {
92 } catch (Exception err) {
93 Reject(err);
94 return;
79 }
95 }
96 }
97 if (medium != null)
98 medium.Cancel();
80 }
99 }
81 }
100 }
82
101
83 const int UNRESOLVED_SATE = 0;
102 const int UNRESOLVED_SATE = 0;
84 const int TRANSITIONAL_STATE = 1;
103 const int TRANSITIONAL_STATE = 1;
85 const int SUCCEEDED_STATE = 2;
104 const int SUCCEEDED_STATE = 2;
86 const int REJECTED_STATE = 3;
105 const int REJECTED_STATE = 3;
87 const int CANCELLED_STATE = 4;
106 const int CANCELLED_STATE = 4;
88
107
89 readonly bool m_cancellable;
108 readonly bool m_cancellable;
90
109
91 int m_childrenCount = 0;
110 int m_childrenCount = 0;
92 int m_state;
111 int m_state;
93 T m_result;
112 T m_result;
94 Exception m_error;
113 Exception m_error;
95
114
96 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
115 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
97
116
98 public Promise() {
117 public Promise() {
99 m_cancellable = true;
118 m_cancellable = true;
100 }
119 }
101
120
102 public Promise(IPromise parent, bool cancellable) {
121 public Promise(IPromise parent, bool cancellable) {
103 m_cancellable = cancellable;
122 m_cancellable = cancellable;
104 if (parent != null)
123 if (parent != null)
105 AddHandler(
124 Cancelled(() => {
106 null,
125 if (parent.IsExclusive)
107 null,
126 parent.Cancel();
108 () => {
127 });
109 if (parent.IsExclusive)
110 parent.Cancel();
111 }
112 );
113 }
128 }
114
129
115 bool BeginTransit() {
130 bool BeginTransit() {
116 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
131 return UNRESOLVED_SATE == Interlocked.CompareExchange(ref m_state, TRANSITIONAL_STATE, UNRESOLVED_SATE);
117 }
132 }
118
133
119 void CompleteTransit(int state) {
134 void CompleteTransit(int state) {
120 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
135 if (TRANSITIONAL_STATE != Interlocked.CompareExchange(ref m_state, state, TRANSITIONAL_STATE))
121 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
136 throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
122 }
137 }
123
138
124 void WaitTransition() {
139 void WaitTransition() {
125 while (m_state == TRANSITIONAL_STATE) {
140 while (m_state == TRANSITIONAL_STATE) {
126 /* noop */
141 /* noop */
127 }
142 }
128 }
143 }
129
144
130 public bool IsResolved {
145 public bool IsResolved {
131 get {
146 get {
132 return m_state > 1;
147 return m_state > 1;
133 }
148 }
134 }
149 }
135
150
136 public bool IsCancelled {
151 public bool IsCancelled {
137 get {
152 get {
138 return m_state == CANCELLED_STATE;
153 return m_state == CANCELLED_STATE;
139 }
154 }
140 }
155 }
141
156
142 public Type PromiseType {
157 public Type PromiseType {
143 get { return typeof(T); }
158 get { return typeof(T); }
144 }
159 }
145
160
146 /// <summary>
161 /// <summary>
147 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ.
162 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ.
148 /// </summary>
163 /// </summary>
149 /// <param name="result">Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния.</param>
164 /// <param name="result">Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния.</param>
150 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
165 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
151 public void Resolve(T result) {
166 public void Resolve(T result) {
152 if (BeginTransit()) {
167 if (BeginTransit()) {
153 m_result = result;
168 m_result = result;
154 CompleteTransit(SUCCEEDED_STATE);
169 CompleteTransit(SUCCEEDED_STATE);
155 OnStateChanged();
170 OnStateChanged();
156 } else {
171 } else {
157 WaitTransition();
172 WaitTransition();
158 if (m_state != CANCELLED_STATE)
173 if (m_state != CANCELLED_STATE)
159 throw new InvalidOperationException("The promise is already resolved");
174 throw new InvalidOperationException("The promise is already resolved");
160 }
175 }
161 }
176 }
162
177
163 /// <summary>
178 /// <summary>
164 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
179 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ выполнСния Π±ΡƒΠ΄Π΅Ρ‚ пустоС значСния.
165 /// </summary>
180 /// </summary>
166 /// <remarks>
181 /// <remarks>
167 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
182 /// Π”Π°Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΡƒΠ΄ΠΎΠ±Π΅Π½ Π² случаях, ΠΊΠΎΠ³Π΄Π° интСрСсСн Ρ„Π°ΠΊΡ‚ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π΅ΠΆΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
168 /// </remarks>
183 /// </remarks>
169 public void Resolve() {
184 public void Resolve() {
170 Resolve(default(T));
185 Resolve(default(T));
171 }
186 }
172
187
173 /// <summary>
188 /// <summary>
174 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
189 /// ВыполняСт ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, сообщая ΠΎΠ± ошибкС
175 /// </summary>
190 /// </summary>
176 /// <remarks>
191 /// <remarks>
177 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
192 /// ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС, ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
178 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
193 /// ΠΌΠΎΠ³Ρƒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΏΡ€ΠΈ этом Ρ‚ΠΎΠ»ΡŒΠΊΠΎ пСрвая Π±ΡƒΠ΄Π΅Ρ‚ использована Π² качСствС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅
179 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
194 /// Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹.
180 /// </remarks>
195 /// </remarks>
181 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
196 /// <param name="error">Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ</param>
182 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
197 /// <exception cref="InvalidOperationException">Π”Π°Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ</exception>
183 public void Reject(Exception error) {
198 public void Reject(Exception error) {
184 if (BeginTransit()) {
199 if (BeginTransit()) {
185 m_error = error;
200 m_error = error;
186 CompleteTransit(REJECTED_STATE);
201 CompleteTransit(REJECTED_STATE);
187 OnStateChanged();
202 OnStateChanged();
188 } else {
203 } else {
189 WaitTransition();
204 WaitTransition();
190 if (m_state == SUCCEEDED_STATE)
205 if (m_state == SUCCEEDED_STATE)
191 throw new InvalidOperationException("The promise is already resolved");
206 throw new InvalidOperationException("The promise is already resolved");
192 }
207 }
193 }
208 }
194
209
195 /// <summary>
210 /// <summary>
196 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
211 /// ΠžΡ‚ΠΌΠ΅Π½ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
197 /// </summary>
212 /// </summary>
198 /// <returns><c>true</c> ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π±Ρ‹Π»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹.<c>false</c> ΠΎΡ‚ΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ.</returns>
213 /// <returns><c>true</c> ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π±Ρ‹Π»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹.<c>false</c> ΠΎΡ‚ΠΌΠ΅Π½Π° Π½Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ.</returns>
199 public bool Cancel() {
214 public bool Cancel() {
200 if (BeginTransit()) {
215 if (m_cancellable && BeginTransit()) {
201 CompleteTransit(CANCELLED_STATE);
216 CompleteTransit(CANCELLED_STATE);
202 OnStateChanged();
217 OnStateChanged();
203 return true;
218 return true;
204 } else {
205 return false;
206 }
219 }
220 return false;
207 }
221 }
208
222
209 // сдСлано для Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° void
223 // сдСлано для Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° void
210 protected void InternalCancel() {
224 protected void InternalCancel() {
211 Cancel();
225 Cancel();
212 }
226 }
213
227
214 /// <summary>
228 /// <summary>
215 /// Adds new handlers to this promise.
229 /// Adds new handlers to this promise.
216 /// </summary>
230 /// </summary>
217 /// <param name="success">The handler of the successfully completed operation.
231 /// <param name="success">The handler of the successfully completed operation.
218 /// This handler will recieve an operation result as a parameter.</param>
232 /// This handler will recieve an operation result as a parameter.</param>
219 /// <param name="error">Handles an exception that may occur during the operation.</param>
220 /// <returns>The new promise chained to this one.</returns>
221 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler error) {
222 if (success == null && error == null)
223 return this;
224
225 var medium = new Promise<T>(this, true);
226
227 ResultHandler<T> resultHandler;
228 if (success != null)
229 resultHandler = x => {
230 success(x);
231 medium.Resolve(x);
232 };
233 else
234 resultHandler = medium.Resolve;
235
236 ErrorHandler errorHandler;
237 if (error != null)
238 errorHandler = x => {
239 // нСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки вызываСтся бСзопасно,
240 // Ρ‚.Π΅. возникшиС Π² Π½Π΅ΠΌ ошибки Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π°Π²Π»Π΅Π½Ρ‹, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ
241 // Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ошибка Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
242 try {
243 error(x);
244 } catch { }
245 medium.Reject(x);
246 };
247 else
248 errorHandler = medium.Reject;
249
250 AddHandler(resultHandler, errorHandler, medium.InternalCancel);
251
252 return medium;
253 }
254
255 public IPromise Then(Action success, ErrorHandler error) {
256 return Then(x => success(), error);
257 }
258
259 public IPromise Then(Action success) {
260 return Then(x => success());
261 }
262
263 /// <summary>
264 /// Adds new handlers to this promise.
265 /// </summary>
266 /// <param name="success">The handler of the successfully completed operation.
267 /// This handler will recieve an operation result as a parameter.</param>
268 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
233 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
269 /// <returns>The new promise chained to this one.</returns>
234 /// <returns>The new promise chained to this one.</returns>
270 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) {
235 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) {
271 if (success == null && error == null)
236 if (success == null && error == null)
272 return this;
237 return this;
273
238
274 var medium = new Promise<T>(this, true);
239 var medium = new Promise<T>(this, true);
275
240
276 ResultHandler<T> resultHandler;
241 AddHandler(success, error, null, medium);
277 ErrorHandler errorHandler;
278
279 if (success != null)
280 resultHandler = x => {
281 success(x);
282 medium.Resolve(x);
283 };
284 else
285 resultHandler = medium.Resolve;
286
287 if (error != null)
288 errorHandler = x => {
289 try {
290 medium.Resolve(error(x));
291 } catch (Exception e) {
292 medium.Reject(e);
293 }
294 };
295 else
296 errorHandler = medium.Reject;
297
298 AddHandler(resultHandler, errorHandler, medium.InternalCancel);
299
242
300 return medium;
243 return medium;
301 }
244 }
302
245
246 public IPromise Then(Action success, ErrorHandler error) {
247 return Then(
248 x => success(),
249 e => {
250 error(e);
251 return default(T);
252 }
253 );
254 }
255
256 public IPromise Then(Action success) {
257 return Then(x => success());
258 }
259
303
260
304 public IPromise<T> Then(ResultHandler<T> success) {
261 public IPromise<T> Then(ResultHandler<T> success) {
305 if (success == null)
262 if (success == null)
306 return this;
263 return this;
307
264
308 var medium = new Promise<T>(this, true);
265 var medium = new Promise<T>(this, true);
309
266
310 ResultHandler<T> resultHandler;
267 AddHandler(success, null, null, medium);
311
312 if (success != null)
313 resultHandler = x => {
314 success(x);
315 medium.Resolve(x);
316 };
317 else
318 resultHandler = medium.Resolve;
319
320 AddHandler(resultHandler, medium.Reject, medium.InternalCancel);
321
268
322 return medium;
269 return medium;
323 }
270 }
324
271
325 public IPromise<T> Error(ErrorHandler error) {
272 public IPromise Error(ErrorHandler error) {
326 return Then((ResultHandler<T>)null, error);
273 if (error == null)
274 return this;
275
276 var medium = new Promise<T>(this, true);
277
278 AddHandler(
279 null,
280 e => {
281 error(e);
282 return default(T);
283 },
284 null,
285 medium
286 );
287
288 return medium;
327 }
289 }
328
290
329 /// <summary>
291 /// <summary>
330 /// Handles error and allows to keep the promise.
292 /// Handles error and allows to keep the promise.
331 /// </summary>
293 /// </summary>
332 /// <remarks>
294 /// <remarks>
333 /// If the specified handler throws an exception, this exception will be used to reject the promise.
295 /// If the specified handler throws an exception, this exception will be used to reject the promise.
334 /// </remarks>
296 /// </remarks>
335 /// <param name="handler">The error handler which returns the result of the promise.</param>
297 /// <param name="handler">The error handler which returns the result of the promise.</param>
336 /// <returns>New promise.</returns>
298 /// <returns>New promise.</returns>
337 public IPromise<T> Error(ErrorHandler<T> handler) {
299 public IPromise<T> Error(ErrorHandler<T> handler) {
338 if (handler == null)
300 if (handler == null)
339 return this;
301 return this;
340
302
341 var medium = new Promise<T>(this, true);
303 var medium = new Promise<T>(this, true);
342
304
343 AddHandler(
305 AddHandler(null, handler, null, medium);
344 x => medium.Resolve(x),
345 e => {
346 try {
347 medium.Resolve(handler(e));
348 } catch (Exception e2) {
349 medium.Reject(e2);
350 }
351 },
352 medium.InternalCancel
353 );
354
306
355 return medium;
307 return medium;
356 }
308 }
357
309
358 public IPromise<T> Anyway(Action handler) {
310 public IPromise<T> Anyway(Action handler) {
359 if (handler == null)
311 if (handler == null)
360 return this;
312 return this;
361
313
362 var medium = new Promise<T>(this,true);
314 var medium = new Promise<T>(this, true);
363
315
364 AddHandler(
316 AddHandler(
365 x => {
317 x => handler(),
366 // to avoid handler being called multiple times we handle exception by ourselfs
318 e => {
367 try {
319 handler();
368 handler();
320 throw new TransientPromiseException(e);
369 medium.Resolve(x);
370 } catch (Exception e) {
371 medium.Reject(e);
372 }
373 },
321 },
374
322 null,
375 e => {
323 medium
376 try {
377 handler();
378 } catch { }
379 medium.Reject(e);
380 },
381
382 medium.InternalCancel
383 );
324 );
384
325
385 return medium;
326 return medium;
386 }
327 }
387
328
388 /// <summary>
329 /// <summary>
389 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.
330 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.
390 /// </summary>
331 /// </summary>
391 /// <typeparam name="TNew">Новый Ρ‚ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.</typeparam>
332 /// <typeparam name="TNew">Новый Ρ‚ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.</typeparam>
392 /// <param name="mapper">ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.</param>
333 /// <param name="mapper">ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΊ Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ.</param>
393 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
334 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
394 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
335 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
395 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ исходного обСщания.</returns>
336 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ исходного обСщания.</returns>
396 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler error) {
337 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<T> error) {
397 if (mapper == null)
338 if (mapper == null)
398 throw new ArgumentNullException("mapper");
339 throw new ArgumentNullException("mapper");
399
340
400 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
341 // создаСм ΠΏΡ€ΠΈΡ†Π΅ΠΏΠ»Π΅Π½Π½ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
401 var chained = new Promise<TNew>(this,true);
342 var chained = new Promise<TNew>(this, true);
402
343
403 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
344 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
404 ErrorHandler errorHandler = delegate(Exception e) {
345 ErrorHandler<T> errorHandler;
405 if (error != null)
346 if (error != null)
347 errorHandler = e => {
406 try {
348 try {
407 error(e);
349 return error(e);
408 } catch { }
350 } catch (Exception e2) {
409 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
351 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
410 chained.Reject(e);
352 chained.Reject(e2);
411 };
353 }
354 return default(T);
355 };
356 else
357 errorHandler = e => {
358 chained.Reject(e);
359 return default(T);
360 };
412
361
413
362
414 AddHandler(
363 AddHandler(
415 resultHandler,
364 resultHandler,
416 errorHandler,
365 errorHandler,
417 chained.InternalCancel
366 chained.InternalCancel,
367 null
418 );
368 );
419
369
420 return chained;
370 return chained;
421 }
371 }
422
372
423 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper) {
373 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper) {
424 return Map(mapper, null);
374 return Map(mapper, null);
425 }
375 }
426
376
427 /// <summary>
377 /// <summary>
428 /// БцСпляСт нСсколько аснхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Указанная асинхронная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° послС
378 /// БцСпляСт нСсколько аснхронных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Указанная асинхронная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° послС
429 /// выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
379 /// выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
430 /// Π½ΠΎΠ²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
380 /// Π½ΠΎΠ²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
431 /// </summary>
381 /// </summary>
432 /// <typeparam name="TNew">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</typeparam>
382 /// <typeparam name="TNew">Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ асинхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</typeparam>
433 /// <param name="chained">Асинхронная опСрация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒΡΡ послС выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ.</param>
383 /// <param name="chained">Асинхронная опСрация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒΡΡ послС выполнСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ.</param>
434 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
384 /// <param name="error">ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибки. Π”Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚
435 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΠ΅Ρ‰ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
385 /// ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ возникшСС ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΠ΅Ρ‰ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
436 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ аснхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</returns>
386 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ аснхронной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</returns>
437 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler error) {
387 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler<T> error) {
438
388
439 // ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ связывания Π΅Ρ‰Π΅ Π½Π΅ Π½Π°Ρ‡Π°Ρ‚Π° асинхронная опСрация, поэтому Π½ΡƒΠΆΠ½ΠΎ
389 // ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ связывания Π΅Ρ‰Π΅ Π½Π΅ Π½Π°Ρ‡Π°Ρ‚Π° асинхронная опСрация, поэтому Π½ΡƒΠΆΠ½ΠΎ
440 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π²Ρ‹Π·ΡΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
390 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ посрСдника, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄Π²Ρ‹Π·ΡΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
441 // ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ асинхронная опСрация, ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ посрСднику, Ρ‡Ρ‚ΠΎΠ±Ρ‹
391 // ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Π°Ρ асинхронная опСрация, ΠΎΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ посрСднику, Ρ‡Ρ‚ΠΎΠ±Ρ‹
442 // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
392 // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹.
443 var medium = new Promise<TNew>(this, true);
393 var medium = new Promise<TNew>(this, true);
444
394
445 ResultHandler<T> resultHandler = delegate(T result) {
395 ResultHandler<T> resultHandler = delegate(T result) {
446 if (medium.IsCancelled)
396 if (medium.IsCancelled)
447 return;
397 return;
448
398
449 var promise = chained(result);
399 var promise = chained(result);
450
400
451 promise.Then(
401 promise.Then(
452 x => medium.Resolve(x),
402 medium.Resolve,
453 e => medium.Reject(e)
403 err => {
404 medium.Reject(err);
405 throw new TransientPromiseException(err);
406 }
454 );
407 );
455
408
456 // notify chained operation that it's not needed anymore
409 // notify chained operation that it's not needed anymore
457 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
410 // порядок Π²Ρ‹Π·ΠΎΠ²Π° Then, Cancelled Π²Π°ΠΆΠ΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΡ‚ этого
458 // зависит IsExclusive
411 // зависит IsExclusive
459 medium.Cancelled(() => {
412 medium.Cancelled(() => {
460 if(promise.IsExclusive)
413 if (promise.IsExclusive)
461 promise.Cancel();
414 promise.Cancel();
462 });
415 });
463
416
464 // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
417 // внСшняя ΠΎΡ‚ΠΌΠ΅Π½Π° связанной ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ рассматриваСтся ΠΊΠ°ΠΊ ошибка
465 promise.Cancelled(() => medium.Reject(new OperationCanceledException()));
418 promise.Cancelled(() => medium.Reject(new OperationCanceledException()));
466 };
419 };
467
420
468 ErrorHandler errorHandler = delegate(Exception e) {
421 ErrorHandler<T> errorHandler = delegate(Exception e) {
469 if (error != null)
422 if (error != null) {
470 error(e);
423 try {
424 return error(e);
425 } catch (Exception e2) {
426 medium.Reject(e2);
427 return default(T);
428 }
429 }
471 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
430 // Π² случаС ошибки Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ дальшС ΠΏΠΎ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅
472 medium.Reject(e);
431 medium.Reject(e);
432 return default(T);
473 };
433 };
474
434
475 AddHandler(
435 AddHandler(
476 resultHandler,
436 resultHandler,
477 errorHandler,
437 errorHandler,
478 medium.InternalCancel
438 medium.InternalCancel,
439 null
479 );
440 );
480
441
481 return medium;
442 return medium;
482 }
443 }
483
444
484 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained) {
445 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained) {
485 return Chain(chained, null);
446 return Chain(chained, null);
486 }
447 }
487
448
488 public IPromise<T> Cancelled(Action handler) {
449 public IPromise<T> Cancelled(Action handler) {
489 AddHandler(null, null, handler);
450 AddHandler(null, null, handler, null);
490 return this;
451 return this;
491 }
452 }
492
453
493 /// <summary>
454 /// <summary>
494 /// Adds the specified handler for all cases (success, error, cancel)
455 /// Adds the specified handler for all cases (success, error, cancel)
495 /// </summary>
456 /// </summary>
496 /// <param name="handler">The handler that will be called anyway</param>
457 /// <param name="handler">The handler that will be called anyway</param>
497 /// <returns>self</returns>
458 /// <returns>self</returns>
498 public IPromise<T> Finally(Action handler) {
459 public IPromise<T> Finally(Action handler) {
499 if (handler == null)
460 if (handler == null)
500 throw new ArgumentNullException("handler");
461 throw new ArgumentNullException("handler");
501 AddHandler(
462 AddHandler(
502 x => handler(),
463 x => handler(),
503 e => handler(),
464 e => {
504 handler
465 handler();
466 throw new TransientPromiseException(e);
467 },
468 handler,
469 null
505 );
470 );
506 return this;
471 return this;
507 }
472 }
508
473
509 /// <summary>
474 /// <summary>
510 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ
475 /// ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ обСщания ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ
511 /// </summary>
476 /// </summary>
512 /// <typeparam name="T2"></typeparam>
477 /// <typeparam name="T2"></typeparam>
513 /// <returns></returns>
478 /// <returns></returns>
514 public IPromise<T2> Cast<T2>() {
479 public IPromise<T2> Cast<T2>() {
515 return Map(x => (T2)(object)x, null);
480 return Map(x => (T2)(object)x, null);
516 }
481 }
517
482
518 /// <summary>
483 /// <summary>
519 /// ДоТидаСтся ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ обСщания ΠΈ Π² случаС успСха, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
484 /// ДоТидаСтся ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ обСщания ΠΈ Π² случаС успСха, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
520 /// Π΅Π³ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС бросаСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
485 /// Π΅Π³ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС бросаСт ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
521 /// </summary>
486 /// </summary>
522 /// <remarks>
487 /// <remarks>
523 /// <para>
488 /// <para>
524 /// Если ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ обСщания Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ, это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚,
489 /// Если ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ обСщания Π±Ρ‹Π»ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ, это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚,
525 /// Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² этом Ρ€ΠΎΠ΄Π΅, это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
490 /// Ρ‡Ρ‚ΠΎ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π² этом Ρ€ΠΎΠ΄Π΅, это Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
526 /// ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΅Π³ΠΎ Π½Π΅ доТдались, ΠΎΠ΄Π½Π°ΠΊΠΎ всС зарСгистрированныС
491 /// ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΅Π³ΠΎ Π½Π΅ доТдались, ΠΎΠ΄Π½Π°ΠΊΠΎ всС зарСгистрированныС
527 /// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΈ Ρ‚Π°ΠΊ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΈ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹, ΠΊΠΎΠ³Π΄Π°
492 /// ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΈ Ρ‚Π°ΠΊ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ ΠΈ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Π½Ρ‹, ΠΊΠΎΠ³Π΄Π°
528 /// ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
493 /// ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
529 /// </para>
494 /// </para>
530 /// <para>
495 /// <para>
531 /// Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΡ‚Π΅Ρ‡ΡŒ
496 /// Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΡ‚Π΅Ρ‡ΡŒ
532 /// Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΈ
497 /// Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Π½Π°Ρ‡Π°Π»Π°ΡΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΈ
533 /// ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ
498 /// ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ
534 /// ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ.
499 /// ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π½Π΅ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ.
535 /// </para>
500 /// </para>
536 /// </remarks>
501 /// </remarks>
537 /// <param name="timeout">ВрСмя оТидания</param>
502 /// <param name="timeout">ВрСмя оТидания</param>
538 /// <returns>Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния обСщания</returns>
503 /// <returns>Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния обСщания</returns>
539 public T Join(int timeout) {
504 public T Join(int timeout) {
540 var evt = new ManualResetEvent(false);
505 var evt = new ManualResetEvent(false);
541 Anyway(() => evt.Set());
506 Anyway(() => evt.Set());
542 Cancelled(() => evt.Set());
507 Cancelled(() => evt.Set());
543
508
544 if (!evt.WaitOne(timeout, true))
509 if (!evt.WaitOne(timeout, true))
545 throw new TimeoutException();
510 throw new TimeoutException();
546
511
547 switch (m_state) {
512 switch (m_state) {
548 case SUCCEEDED_STATE:
513 case SUCCEEDED_STATE:
549 return m_result;
514 return m_result;
550 case CANCELLED_STATE:
515 case CANCELLED_STATE:
551 throw new OperationCanceledException();
516 throw new OperationCanceledException();
552 case REJECTED_STATE:
517 case REJECTED_STATE:
553 throw new TargetInvocationException(m_error);
518 throw new TargetInvocationException(m_error);
554 default:
519 default:
555 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
520 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
556 }
521 }
557 }
522 }
558
523
559 public T Join() {
524 public T Join() {
560 return Join(Timeout.Infinite);
525 return Join(Timeout.Infinite);
561 }
526 }
562
527
563 void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) {
528 void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) {
564 if (success != null || error != null)
529 if (success != null || error != null)
565 Interlocked.Increment(ref m_childrenCount);
530 Interlocked.Increment(ref m_childrenCount);
566
531
567 HandlerDescriptor handler = new HandlerDescriptor {
532 var handler = new HandlerDescriptor {
568 resultHandler = success,
533 resultHandler = success,
569 errorHandler = error,
534 errorHandler = error,
570 cancellHandler = cancel
535 cancellHandler = cancel,
536 medium = medium
571 };
537 };
572
538
573 bool queued;
539 bool queued;
574
540
575 if (!IsResolved) {
541 if (!IsResolved) {
576 m_handlers.Enqueue(handler);
542 m_handlers.Enqueue(handler);
577 queued = true;
543 queued = true;
578 } else {
544 } else {
579 // the promise is in resolved state, just invoke the handled with minimum overhead
545 // the promise is in resolved state, just invoke the handled with minimum overhead
580 queued = false;
546 queued = false;
581 InvokeHandler(handler);
547 InvokeHandler(handler);
582 }
548 }
583
549
584 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
550 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
585 // if the promise have been resolved while we was adding handler to the queue
551 // if the promise have been resolved while we was adding handler to the queue
586 // we can't guarantee that someone is still processing it
552 // we can't guarantee that someone is still processing it
587 // therefore we will fetch a handler from the queue and execute it
553 // therefore we will fetch a handler from the queue and execute it
588 // note that fetched handler may be not the one that we have added
554 // note that fetched handler may be not the one that we have added
589 // even we can fetch no handlers at all :)
555 // even we can fetch no handlers at all :)
590 InvokeHandler(handler);
556 InvokeHandler(handler);
591 }
557 }
592
558
593 protected virtual void InvokeHandler(HandlerDescriptor handler) {
559 protected virtual void InvokeHandler(HandlerDescriptor handler) {
594 switch (m_state) {
560 switch (m_state) {
595 case SUCCEEDED_STATE:
561 case SUCCEEDED_STATE:
596 handler.Resolve(m_result);
562 handler.Resolve(m_result);
597 break;
563 break;
598 case REJECTED_STATE:
564 case REJECTED_STATE:
599 handler.Reject(m_error);
565 handler.Reject(m_error);
600 break;
566 break;
601 case CANCELLED_STATE:
567 case CANCELLED_STATE:
602 handler.Cancel();
568 handler.Cancel();
603 break;
569 break;
604 default:
570 default:
605 // do nothing
571 // do nothing
606 return;
572 return;
607 }
573 }
608 }
574 }
609
575
610 void OnStateChanged() {
576 void OnStateChanged() {
611 HandlerDescriptor handler;
577 HandlerDescriptor handler;
612 while (m_handlers.TryDequeue(out handler))
578 while (m_handlers.TryDequeue(out handler))
613 InvokeHandler(handler);
579 InvokeHandler(handler);
614 }
580 }
615
581
616 public bool IsExclusive {
582 public bool IsExclusive {
617 get {
583 get {
618 return m_childrenCount <= 1;
584 return m_childrenCount <= 1;
619 }
585 }
620 }
586 }
621
587
622 /// <summary>
588 /// <summary>
623 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
589 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ являСтся массив Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.
624 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
590 /// Если хотябы ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ, Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ΅ ΠΎΠ±Π΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ.
625 /// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ обСщания, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ обСщания Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹, Ссли Π½ΠΈΠΊΡ‚ΠΎ большС Π½Π° Π½ΠΈΡ… Π½Π΅ подписан.
591 /// ΠŸΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ обСщания, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ обСщания Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹, Ссли Π½ΠΈΠΊΡ‚ΠΎ большС Π½Π° Π½ΠΈΡ… Π½Π΅ подписан.
626 /// </summary>
592 /// </summary>
627 /// <param name="promises">Бписок ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. Если список пустой, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ возвращаСтся ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΌ.</param>
593 /// <param name="promises">Бписок ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. Если список пустой, Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ возвращаСтся ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΌ.</param>
628 /// <returns>ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.</returns>
594 /// <returns>ΠžΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ.</returns>
629 /// <exception cref="ArgumentNullException"><paramref name="promises"/> Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ null</exception>
595 /// <exception cref="ArgumentNullException"><paramref name="promises"/> Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ null</exception>
630 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
596 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
631 if (promises == null)
597 if (promises == null)
632 throw new ArgumentNullException();
598 throw new ArgumentNullException();
633
599
634 // создаСм аккумулятор для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
600 // создаСм аккумулятор для Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅
635 var result = new T[promises.Count];
601 var result = new T[promises.Count];
636 var promise = new Promise<T[]>();
602 var promise = new Promise<T[]>();
637
603
638 // special case
604 // special case
639 if (promises.Count == 0) {
605 if (promises.Count == 0) {
640 promise.Resolve(result);
606 promise.Resolve(result);
641 return promise;
607 return promise;
642 }
608 }
643
609
644 int pending = promises.Count;
610 int pending = promises.Count;
645
611
646 for (int i = 0; i < promises.Count; i++) {
612 for (int i = 0; i < promises.Count; i++) {
647 var dest = i;
613 var dest = i;
648
614
649 if (promises[i] != null) {
615 if (promises[i] != null) {
650 promises[i].Then(
616 promises[i].Then(
651 x => {
617 x => {
652 result[dest] = x;
618 result[dest] = x;
653 if (Interlocked.Decrement(ref pending) == 0)
619 if (Interlocked.Decrement(ref pending) == 0)
654 promise.Resolve(result);
620 promise.Resolve(result);
655 },
621 },
656 e => promise.Reject(e)
622 e => {
623 promise.Reject(e);
624 return default(T);
625 }
657 );
626 );
658 } else {
627 } else {
659 if (Interlocked.Decrement(ref pending) == 0)
628 if (Interlocked.Decrement(ref pending) == 0)
660 promise.Resolve(result);
629 promise.Resolve(result);
661 }
630 }
662 }
631 }
663
632
664 promise.Cancelled(
633 promise.Cancelled(
665 () => {
634 () => {
666 foreach (var d in promises)
635 foreach (var d in promises)
667 if (d != null && d.IsExclusive)
636 if (d != null && d.IsExclusive)
668 d.Cancel();
637 d.Cancel();
669 }
638 }
670 );
639 );
671
640
672 return promise;
641 return promise;
673 }
642 }
674
643
675 /// <summary>
644 /// <summary>
676 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
645 /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ нСсколько ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ Π² ΠΎΠ΄Π½ΠΎ. Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΏΡ€ΠΈ
677 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
646 /// Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ всСх ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ
678 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
647 /// ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
679 /// </summary>
648 /// </summary>
680 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
649 /// <param name="promises">ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΠ±ΡŠΠ΅Π΄Π΅Π½Π΅Π½Ρ‹ Π² ΠΎΠ΄Π½ΠΎ.</param>
681 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
650 /// <returns>НовоС ΠΎΠ±Π΅Ρ‰Π°Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‰Π΅Π΅ Π² сСбС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅.</returns>
682 /// <remarks>
651 /// <remarks>
683 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
652 /// Если Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡŒΡΡ <c>null</c>, Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ обСщания.
684 /// </remarks>
653 /// </remarks>
685 public static IPromise CreateComposite(ICollection<IPromise> promises) {
654 public static IPromise CreateComposite(ICollection<IPromise> promises) {
686 if (promises == null)
655 if (promises == null)
687 throw new ArgumentNullException();
656 throw new ArgumentNullException();
688 if (promises.Count == 0)
657 if (promises.Count == 0)
689 return Promise<object>.ResultToPromise(null);
658 return Promise<object>.ResultToPromise(null);
690
659
691 int countdown = promises.Count;
660 int countdown = promises.Count;
692
661
693 var result = new Promise<object>();
662 var result = new Promise<object>();
694
663
695 foreach (var d in promises) {
664 foreach (var d in promises) {
696 if (d == null) {
665 if (d == null) {
697 if (Interlocked.Decrement(ref countdown) == 0)
666 if (Interlocked.Decrement(ref countdown) == 0)
698 result.Resolve(null);
667 result.Resolve(null);
699 } else {
668 } else {
700 d.Then(() => {
669 d.Then(() => {
701 if (Interlocked.Decrement(ref countdown) == 0)
670 if (Interlocked.Decrement(ref countdown) == 0)
702 result.Resolve(null);
671 result.Resolve(null);
703 });
672 });
704 }
673 }
705 }
674 }
706
675
707 result.Cancelled(() => {
676 result.Cancelled(() => {
708 foreach (var d in promises)
677 foreach (var d in promises)
709 if (d != null && d.IsExclusive)
678 if (d != null && d.IsExclusive)
710 d.Cancel();
679 d.Cancel();
711 });
680 });
712
681
713 return result;
682 return result;
714 }
683 }
715
684
716 public static Promise<T> ResultToPromise(T result) {
685 public static Promise<T> ResultToPromise(T result) {
717 var p = new Promise<T>();
686 var p = new Promise<T>();
718 p.Resolve(result);
687 p.Resolve(result);
719 return p;
688 return p;
720 }
689 }
721
690
722 public static Promise<T> ExceptionToPromise(Exception error) {
691 public static Promise<T> ExceptionToPromise(Exception error) {
723 if (error == null)
692 if (error == null)
724 throw new ArgumentNullException();
693 throw new ArgumentNullException();
725
694
726 var p = new Promise<T>();
695 var p = new Promise<T>();
727 p.Reject(error);
696 p.Reject(error);
728 return p;
697 return p;
729 }
698 }
730
699
731 #region IPromiseBase explicit implementation
700 #region IPromiseBase explicit implementation
732
701
733 IPromise IPromise.Error(ErrorHandler error) {
702 IPromise IPromise.Error(ErrorHandler error) {
734 return Error(error);
703 return Error(error);
735 }
704 }
736
705
737 IPromise IPromise.Anyway(Action handler) {
706 IPromise IPromise.Anyway(Action handler) {
738 return Anyway(handler);
707 return Anyway(handler);
739 }
708 }
740
709
741 IPromise IPromise.Finally(Action handler) {
710 IPromise IPromise.Finally(Action handler) {
742 return Finally(handler);
711 return Finally(handler);
743 }
712 }
744
713
745 IPromise IPromise.Cancelled(Action handler) {
714 IPromise IPromise.Cancelled(Action handler) {
746 return Cancelled(handler);
715 return Cancelled(handler);
747 }
716 }
748
717
749 void IPromise.Join() {
718 void IPromise.Join() {
750 Join();
719 Join();
751 }
720 }
752
721
753 void IPromise.Join(int timeout) {
722 void IPromise.Join(int timeout) {
754 Join(timeout);
723 Join(timeout);
755 }
724 }
756
725
757 #endregion
726 #endregion
758
727
759
728
760
729
761 }
730 }
762 }
731 }
General Comments 0
You need to be logged in to leave comments. Login now