using System; 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 Promise that, Control ctl) { if (that == null) throw new ArgumentNullException("that"); if (ctl == null) throw new ArgumentNullException("ctl"); var directed = new ControlBoundPromise(ctl,that,true); that.Then( directed.Resolve, err => { directed.Reject(err); return default(T); } ); 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 default(T); } ); return d; } } }