annotate Implab.Fx/PromiseHelpers.cs @ 19:e3935fdf59a2 promises

Promise is rewritten to use interlocked operations instead of locks
author cin
date Sun, 10 Nov 2013 00:21:33 +0400
parents 381095ad0a69
children d67b95eddaf4 0fdaf280c797
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
1 using System;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
2 using System.Collections.Generic;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
3 using System.Linq;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
4 using System.Text;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
5 using System.Windows.Forms;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
6 using System.Threading;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
7
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
8 namespace Implab.Fx
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
9 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
10 public static class PromiseHelpers
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
11 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
12 /// <summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
13 /// Перенаправляет обработку обещания в поток указанного элемента управления.
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
14 /// </summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
15 /// <typeparam name="T">Тип результата обещания</typeparam>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
16 /// <param name="that">Исходное обещание</param>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
17 /// <param name="ctl">Элемент управления</param>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
18 /// <returns>Новое обещание, обработчики которого будут выполнены в потоке элемента управления.</returns>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
19 /// <exception cref="ArgumentNullException">Параметр не может быть <c>null</c>.</exception>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
20 /// <example>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
21 /// client
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
22 /// .Get("description.txt") // returns a promise
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
23 /// .DirectToControl(m_ctl) // handle the promise in the thread of the control
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
24 /// .Then(
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
25 /// description => m_ctl.Text = description // now it's safe
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
26 /// )
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
27 /// </example>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
28 public static Promise<T> DispatchToControl<T>(this Promise<T> that, Control ctl)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
29 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
30 if (that == null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
31 throw new ArgumentNullException("that");
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
32 if (ctl == null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
33 throw new ArgumentNullException("ctl");
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
34
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
35 var directed = new Promise<T>();
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
36
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
37 that.Then(
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
38 res =>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
39 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
40 if (ctl.InvokeRequired)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
41 ctl.Invoke(new Action<T>(directed.Resolve), res);
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
42 else
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
43 directed.Resolve(res);
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
44 },
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
45 err =>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
46 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
47 if (ctl.InvokeRequired)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
48 ctl.Invoke(new Action<Exception>(directed.Reject), err);
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
49 else
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
50 directed.Reject(err);
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
51 }
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
52 );
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
53
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
54 return directed;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
55 }
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
56
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
57 /// <summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
58 /// Направляет обработку обещания в текущий поток, если у него существует контекст синхронизации.
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
59 /// </summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
60 /// <typeparam name="T">Тип результата обещания.</typeparam>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
61 /// <param name="that">Обещание которое нужно обработать в текущем потоке.</param>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
62 /// <returns>Перенаправленное обещание.</returns>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
63 public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
64 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
65 var sync = SynchronizationContext.Current;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
66 if (sync == null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
67 throw new InvalidOperationException("The current thread doesn't have a syncronization context");
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
68 return DispatchToSyncContext(that, sync);
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
69 }
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
70
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
71 /// <summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
72 /// Направляет обработку обещания в указанный контекст синхронизации.
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
73 /// </summary>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
74 /// <typeparam name="T">Тип результата обещания.</typeparam>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
75 /// <param name="that">Обещание, которое требуется обработать в указанном контексте синхронизации.</param>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
76 /// <param name="sync">Контекст синхронизации в который будет направлено обещание.</param>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
77 /// <returns>Новое обещание, которое будет обрабатываться в указанном контексте.</returns>
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
78 public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
79 {
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
80 if (that == null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
81 throw new ArgumentNullException("that");
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
82 if (sync == null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
83 throw new ArgumentNullException("sync");
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
84
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
85 var d = new Promise<T>();
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
86
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
87 that.Then(
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
88 res => sync.Post(state => d.Resolve(res), null),
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
89 err => sync.Post(state => d.Reject(err), null)
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
90 );
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
91
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
92 return d;
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
93 }
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
94 }
381095ad0a69 Implab.Fx: implemented animation object
cin
parents:
diff changeset
95 }