Mercurial > pub > ImplabNet
view Implab.Fx/PromiseHelpers.cs @ 22:5a35900264f5 promises
implemented nonblocking wake singnals processing
author | cin |
---|---|
date | Wed, 13 Nov 2013 14:03:00 +0400 |
parents | 381095ad0a69 |
children | d67b95eddaf4 0fdaf280c797 |
line wrap: on
line source
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 Promise<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; } } }