|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Windows.Forms;
|
|
|
using System.Threading;
|
|
|
|
|
|
namespace Implab.Fx
|
|
|
{
|
|
|
public static class PromiseHelpers
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// Перенаправляет обработку обещания в поток указанного элемента управления.
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">Тип результата обещания</typeparam>
|
|
|
/// <param name="that">Исходное обещание</param>
|
|
|
/// <param name="ctl">Элемент управления</param>
|
|
|
/// <returns>Новое обещание, обработчики которого будут выполнены в потоке элемента управления.</returns>
|
|
|
/// <exception cref="ArgumentNullException">Параметр не может быть <c>null</c>.</exception>
|
|
|
/// <example>
|
|
|
/// client
|
|
|
/// .Get("description.txt") // returns a promise
|
|
|
/// .DirectToControl(m_ctl) // handle the promise in the thread of the control
|
|
|
/// .Then(
|
|
|
/// description => m_ctl.Text = description // now it's safe
|
|
|
/// )
|
|
|
/// </example>
|
|
|
public static Promise<T> DispatchToControl<T>(this IPromise<T> that, Control ctl)
|
|
|
{
|
|
|
if (that == null)
|
|
|
throw new ArgumentNullException("that");
|
|
|
if (ctl == null)
|
|
|
throw new ArgumentNullException("ctl");
|
|
|
|
|
|
var directed = new Promise<T>();
|
|
|
|
|
|
that.Then(
|
|
|
res =>
|
|
|
{
|
|
|
if (ctl.InvokeRequired)
|
|
|
ctl.Invoke(new Action<T>(directed.Resolve), res);
|
|
|
else
|
|
|
directed.Resolve(res);
|
|
|
},
|
|
|
err =>
|
|
|
{
|
|
|
if (ctl.InvokeRequired)
|
|
|
ctl.Invoke(new Action<Exception>(directed.Reject), err);
|
|
|
else
|
|
|
directed.Reject(err);
|
|
|
}
|
|
|
);
|
|
|
|
|
|
return directed;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Направляет обработку обещания в текущий поток, если у него существует контекст синхронизации.
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">Тип результата обещания.</typeparam>
|
|
|
/// <param name="that">Обещание которое нужно обработать в текущем потоке.</param>
|
|
|
/// <returns>Перенаправленное обещание.</returns>
|
|
|
public static Promise<T> DispatchToCurrentThread<T>(this Promise<T> that)
|
|
|
{
|
|
|
var sync = SynchronizationContext.Current;
|
|
|
if (sync == null)
|
|
|
throw new InvalidOperationException("The current thread doesn't have a syncronization context");
|
|
|
return DispatchToSyncContext(that, sync);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Направляет обработку обещания в указанный контекст синхронизации.
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">Тип результата обещания.</typeparam>
|
|
|
/// <param name="that">Обещание, которое требуется обработать в указанном контексте синхронизации.</param>
|
|
|
/// <param name="sync">Контекст синхронизации в который будет направлено обещание.</param>
|
|
|
/// <returns>Новое обещание, которое будет обрабатываться в указанном контексте.</returns>
|
|
|
public static Promise<T> DispatchToSyncContext<T>(this Promise<T> that, SynchronizationContext sync)
|
|
|
{
|
|
|
if (that == null)
|
|
|
throw new ArgumentNullException("that");
|
|
|
if (sync == null)
|
|
|
throw new ArgumentNullException("sync");
|
|
|
|
|
|
var d = new Promise<T>();
|
|
|
|
|
|
that.Then(
|
|
|
res => sync.Post(state => d.Resolve(res), null),
|
|
|
err => sync.Post(state => d.Reject(err), null)
|
|
|
);
|
|
|
|
|
|
return d;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|