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