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
{
///
/// Перенаправляет обработку обещания в поток указанного элемента управления.
///
/// Тип результата обещания
/// Исходное обещание
/// Элемент управления
/// Новое обещание, обработчики которого будут выполнены в потоке элемента управления.
/// Параметр не может быть null.
///
/// 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
/// )
///
public static Promise DispatchToControl(this IPromise that, Control ctl)
{
if (that == null)
throw new ArgumentNullException("that");
if (ctl == null)
throw new ArgumentNullException("ctl");
var directed = new Promise();
that.Then(
res =>
{
if (ctl.InvokeRequired)
ctl.Invoke(new Action(directed.Resolve), res);
else
directed.Resolve(res);
},
err =>
{
if (ctl.InvokeRequired)
ctl.Invoke(new Action(directed.Reject), err);
else
directed.Reject(err);
}
);
return directed;
}
///
/// Направляет обработку обещания в текущий поток, если у него существует контекст синхронизации.
///
/// Тип результата обещания.
/// Обещание которое нужно обработать в текущем потоке.
/// Перенаправленное обещание.
public static Promise DispatchToCurrentThread(this Promise that)
{
var sync = SynchronizationContext.Current;
if (sync == null)
throw new InvalidOperationException("The current thread doesn't have a syncronization context");
return DispatchToSyncContext(that, sync);
}
///
/// Направляет обработку обещания в указанный контекст синхронизации.
///
/// Тип результата обещания.
/// Обещание, которое требуется обработать в указанном контексте синхронизации.
/// Контекст синхронизации в который будет направлено обещание.
/// Новое обещание, которое будет обрабатываться в указанном контексте.
public static Promise DispatchToSyncContext(this Promise that, SynchronizationContext sync)
{
if (that == null)
throw new ArgumentNullException("that");
if (sync == null)
throw new ArgumentNullException("sync");
var d = new Promise();
that.Then(
res => sync.Post(state => d.Resolve(res), null),
err => sync.Post(state => d.Reject(err), null)
);
return d;
}
}
}