Mercurial > pub > ImplabNet
comparison Implab/Promise.cs @ 101:279e226dffdd v2
code cleanup
added EnsureDispatched extension
| author | cin |
|---|---|
| date | Thu, 06 Nov 2014 20:03:19 +0300 |
| parents | 8ddf1648eca4 |
| children | 5f10d54b45df |
comparison
equal
deleted
inserted
replaced
| 100:673947ce458a | 101:279e226dffdd |
|---|---|
| 1 using System; | 1 using System; |
| 2 using System.Collections.Generic; | 2 using System.Collections.Generic; |
| 3 using System.Reflection; | 3 using System.Reflection; |
| 4 using System.Diagnostics; | |
| 5 using System.Threading; | 4 using System.Threading; |
| 6 using Implab.Parallels; | 5 using Implab.Parallels; |
| 7 | 6 |
| 8 namespace Implab { | 7 namespace Implab { |
| 9 | |
| 10 public delegate void ErrorHandler(Exception e); | |
| 11 public delegate T ErrorHandler<out T>(Exception e); | |
| 12 public delegate void ResultHandler<in T>(T result); | |
| 13 public delegate TNew ResultMapper<in TSrc,out TNew>(TSrc result); | |
| 14 | 8 |
| 15 /// <summary> | 9 /// <summary> |
| 16 /// Класс для асинхронного получения результатов. Так называемое "обещание". | 10 /// Класс для асинхронного получения результатов. Так называемое "обещание". |
| 17 /// </summary> | 11 /// </summary> |
| 18 /// <typeparam name="T">Тип получаемого результата</typeparam> | 12 /// <typeparam name="T">Тип получаемого результата</typeparam> |
| 47 /// </para> | 41 /// </para> |
| 48 /// </remarks> | 42 /// </remarks> |
| 49 public class Promise<T> : IPromise<T> { | 43 public class Promise<T> : IPromise<T> { |
| 50 | 44 |
| 51 protected struct HandlerDescriptor { | 45 protected struct HandlerDescriptor { |
| 52 public ResultHandler<T> resultHandler; | 46 public Action<T> resultHandler; |
| 53 public ErrorHandler<T> errorHandler; | 47 public Func<Exception,T> errorHandler; |
| 54 public Action cancellHandler; | 48 public Action cancellHandler; |
| 55 public Promise<T> medium; | 49 public Promise<T> medium; |
| 56 | 50 |
| 57 public void Resolve(T result) { | 51 public void Resolve(T result) { |
| 58 if (resultHandler != null) { | 52 if (resultHandler != null) { |
| 102 const int TRANSITIONAL_STATE = 1; | 96 const int TRANSITIONAL_STATE = 1; |
| 103 const int SUCCEEDED_STATE = 2; | 97 const int SUCCEEDED_STATE = 2; |
| 104 const int REJECTED_STATE = 3; | 98 const int REJECTED_STATE = 3; |
| 105 const int CANCELLED_STATE = 4; | 99 const int CANCELLED_STATE = 4; |
| 106 | 100 |
| 107 readonly bool m_cancellable; | 101 int m_childrenCount; |
| 108 | |
| 109 int m_childrenCount = 0; | |
| 110 int m_state; | 102 int m_state; |
| 111 T m_result; | 103 T m_result; |
| 112 Exception m_error; | 104 Exception m_error; |
| 113 | 105 |
| 114 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>(); | 106 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>(); |
| 115 | 107 |
| 116 public Promise() { | 108 public Promise() { |
| 117 m_cancellable = true; | 109 } |
| 118 } | 110 |
| 119 | 111 public Promise(IPromise parent) { |
| 120 public Promise(IPromise parent, bool cancellable) { | |
| 121 m_cancellable = cancellable; | |
| 122 if (parent != null) | 112 if (parent != null) |
| 123 AddHandler( | 113 AddHandler( |
| 124 null, | 114 null, |
| 125 null, | 115 null, |
| 126 () => { | 116 () => { |
| 216 /// <summary> | 206 /// <summary> |
| 217 /// Отменяет операцию, если это возможно. | 207 /// Отменяет операцию, если это возможно. |
| 218 /// </summary> | 208 /// </summary> |
| 219 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> | 209 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> |
| 220 public void Cancel() { | 210 public void Cancel() { |
| 221 if (m_cancellable && BeginTransit()) { | 211 if (BeginTransit()) { |
| 222 CompleteTransit(CANCELLED_STATE); | 212 CompleteTransit(CANCELLED_STATE); |
| 223 OnStateChanged(); | 213 OnStateChanged(); |
| 224 } | 214 } |
| 225 } | 215 } |
| 226 | 216 |
| 227 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error, Action cancel) { | 217 public IPromise<T> Then(Action<T> success, Func<Exception,T> error, Action cancel) { |
| 228 if (success == null && error == null && cancel == null) | 218 if (success == null && error == null && cancel == null) |
| 229 return this; | 219 return this; |
| 230 | 220 |
| 231 var medium = new Promise<T>(this, true); | 221 var medium = new Promise<T>(this); |
| 232 | 222 |
| 233 AddHandler(success, error, cancel, medium); | 223 AddHandler(success, error, cancel, medium); |
| 234 | 224 |
| 235 return medium; | 225 return medium; |
| 236 } | 226 } |
| 240 /// </summary> | 230 /// </summary> |
| 241 /// <param name="success">The handler of the successfully completed operation. | 231 /// <param name="success">The handler of the successfully completed operation. |
| 242 /// This handler will recieve an operation result as a parameter.</param> | 232 /// This handler will recieve an operation result as a parameter.</param> |
| 243 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param> | 233 /// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param> |
| 244 /// <returns>The new promise chained to this one.</returns> | 234 /// <returns>The new promise chained to this one.</returns> |
| 245 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) { | 235 public IPromise<T> Then(Action<T> success, Func<Exception,T> error) { |
| 246 if (success == null && error == null) | 236 if (success == null && error == null) |
| 247 return this; | 237 return this; |
| 248 | 238 |
| 249 var medium = new Promise<T>(this, true); | 239 var medium = new Promise<T>(this); |
| 250 | 240 |
| 251 AddHandler(success, error, null, medium); | 241 AddHandler(success, error, null, medium); |
| 252 | 242 |
| 253 return medium; | 243 return medium; |
| 254 } | 244 } |
| 255 | 245 |
| 256 | 246 |
| 257 | 247 |
| 258 | 248 |
| 259 public IPromise<T> Then(ResultHandler<T> success) { | 249 public IPromise<T> Then(Action<T> success) { |
| 260 if (success == null) | 250 if (success == null) |
| 261 return this; | 251 return this; |
| 262 | 252 |
| 263 var medium = new Promise<T>(this, true); | 253 var medium = new Promise<T>(this); |
| 264 | 254 |
| 265 AddHandler(success, null, null, medium); | 255 AddHandler(success, null, null, medium); |
| 266 | 256 |
| 267 return medium; | 257 return medium; |
| 268 } | 258 } |
| 282 /// Если данный метод вызвать несколько раз, либо добавить другие обработчики, то цепочка | 272 /// Если данный метод вызвать несколько раз, либо добавить другие обработчики, то цепочка |
| 283 /// не будет одиночной <see cref="IsExclusive"/> и, как следствие, будет невозможна отмена | 273 /// не будет одиночной <see cref="IsExclusive"/> и, как следствие, будет невозможна отмена |
| 284 /// всей цепи обещаний снизу (с самого последнего обещания). | 274 /// всей цепи обещаний снизу (с самого последнего обещания). |
| 285 /// </para> | 275 /// </para> |
| 286 /// </remarks> | 276 /// </remarks> |
| 287 public void Last(ResultHandler<T> success, ErrorHandler error, Action cancel) { | 277 public void Last(Action<T> success, Action<Exception> error, Action cancel) { |
| 288 if (success == null && error == null && cancel == null) | 278 if (success == null && error == null && cancel == null) |
| 289 return; | 279 return; |
| 290 | 280 |
| 291 ErrorHandler<T> errorHandler = null; | 281 Func<Exception,T> errorHandler = null; |
| 292 if (error != null) | 282 if (error != null) |
| 293 errorHandler = err => { | 283 errorHandler = err => { |
| 294 error(err); | 284 error(err); |
| 295 return default(T); | 285 return default(T); |
| 296 }; | 286 }; |
| 297 AddHandler(success, errorHandler, cancel, null); | 287 AddHandler(success, errorHandler, cancel, null); |
| 298 } | 288 } |
| 299 | 289 |
| 300 public void Last(ResultHandler<T> success, ErrorHandler error) { | 290 public void Last(Action<T> success, Action<Exception> error) { |
| 301 Last(success, error, null); | 291 Last(success, error, null); |
| 302 } | 292 } |
| 303 | 293 |
| 304 public void Last(ResultHandler<T> success) { | 294 public void Last(Action<T> success) { |
| 305 Last(success, null, null); | 295 Last(success, null, null); |
| 306 } | 296 } |
| 307 | 297 |
| 308 public IPromise Error(ErrorHandler error) { | 298 public IPromise Error(Action<Exception> error) { |
| 309 if (error == null) | 299 if (error == null) |
| 310 return this; | 300 return this; |
| 311 | 301 |
| 312 var medium = new Promise<T>(this, true); | 302 var medium = new Promise<T>(this); |
| 313 | 303 |
| 314 AddHandler( | 304 AddHandler( |
| 315 null, | 305 null, |
| 316 e => { | 306 e => { |
| 317 error(e); | 307 error(e); |
| 330 /// <remarks> | 320 /// <remarks> |
| 331 /// If the specified handler throws an exception, this exception will be used to reject the promise. | 321 /// If the specified handler throws an exception, this exception will be used to reject the promise. |
| 332 /// </remarks> | 322 /// </remarks> |
| 333 /// <param name="handler">The error handler which returns the result of the promise.</param> | 323 /// <param name="handler">The error handler which returns the result of the promise.</param> |
| 334 /// <returns>New promise.</returns> | 324 /// <returns>New promise.</returns> |
| 335 public IPromise<T> Error(ErrorHandler<T> handler) { | 325 public IPromise<T> Error(Func<Exception,T> handler) { |
| 336 if (handler == null) | 326 if (handler == null) |
| 337 return this; | 327 return this; |
| 338 | 328 |
| 339 var medium = new Promise<T>(this, true); | 329 var medium = new Promise<T>(this); |
| 340 | 330 |
| 341 AddHandler(null, handler, null, medium); | 331 AddHandler(null, handler, null, medium); |
| 342 | 332 |
| 343 return medium; | 333 return medium; |
| 344 } | 334 } |
| 350 /// <param name="mapper">Преобразование результата к новому типу.</param> | 340 /// <param name="mapper">Преобразование результата к новому типу.</param> |
| 351 /// <param name="error">Обработчик ошибки. Данный обработчик получит | 341 /// <param name="error">Обработчик ошибки. Данный обработчик получит |
| 352 /// исключение возникшее при выполнении операции.</param> | 342 /// исключение возникшее при выполнении операции.</param> |
| 353 /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> | 343 /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> |
| 354 /// <param name = "cancel"></param> | 344 /// <param name = "cancel"></param> |
| 355 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error, Action cancel) { | 345 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error, Action cancel) { |
| 356 Safe.ArgumentNotNull(mapper, "mapper"); | 346 Safe.ArgumentNotNull(mapper, "mapper"); |
| 357 | 347 |
| 358 // создаем прицепленное обещание | 348 // создаем прицепленное обещание |
| 359 var medium = new Promise<TNew>(this, true); | 349 var medium = new Promise<TNew>(this); |
| 360 | 350 |
| 361 ResultHandler<T> resultHandler = result => medium.Resolve(mapper(result)); | 351 Action<T> resultHandler = result => medium.Resolve(mapper(result)); |
| 362 ErrorHandler<T> errorHandler; | 352 Func<Exception,T> errorHandler; |
| 363 if (error != null) | 353 if (error != null) |
| 364 errorHandler = e => { | 354 errorHandler = e => { |
| 365 try { | 355 try { |
| 366 medium.Resolve(error(e)); | 356 medium.Resolve(error(e)); |
| 367 } catch (Exception e2) { | 357 } catch (Exception e2) { |
| 394 ); | 384 ); |
| 395 | 385 |
| 396 return medium; | 386 return medium; |
| 397 } | 387 } |
| 398 | 388 |
| 399 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error) { | 389 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper, Func<Exception,TNew> error) { |
| 400 return Then(mapper, error, null); | 390 return Then(mapper, error, null); |
| 401 } | 391 } |
| 402 | 392 |
| 403 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper) { | 393 public IPromise<TNew> Then<TNew>(Func<T, TNew> mapper) { |
| 404 return Then(mapper, null, null); | 394 return Then(mapper, null, null); |
| 405 } | 395 } |
| 406 | 396 |
| 407 /// <summary> | 397 /// <summary> |
| 408 /// Сцепляет несколько аснхронных операций. Указанная асинхронная операция будет вызвана после | 398 /// Сцепляет несколько аснхронных операций. Указанная асинхронная операция будет вызвана после |
| 413 /// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param> | 403 /// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param> |
| 414 /// <param name="error">Обработчик ошибки. Данный обработчик получит | 404 /// <param name="error">Обработчик ошибки. Данный обработчик получит |
| 415 /// исключение возникшее при выполнении текуещй операции.</param> | 405 /// исключение возникшее при выполнении текуещй операции.</param> |
| 416 /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> | 406 /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> |
| 417 /// <param name = "cancel"></param> | 407 /// <param name = "cancel"></param> |
| 418 public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error, Action cancel) { | 408 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error, Action cancel) { |
| 419 | 409 |
| 420 Safe.ArgumentNotNull(chained, "chained"); | 410 Safe.ArgumentNotNull(chained, "chained"); |
| 421 | 411 |
| 422 // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно | 412 // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно |
| 423 // создать посредника, к которому будут подвызяваться следующие обработчики. | 413 // создать посредника, к которому будут подвызяваться следующие обработчики. |
| 424 // когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы | 414 // когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы |
| 425 // передать через него результаты работы. | 415 // передать через него результаты работы. |
| 426 var medium = new Promise<TNew>(this, true); | 416 var medium = new Promise<TNew>(this); |
| 427 | 417 |
| 428 ResultHandler<T> resultHandler = delegate(T result) { | 418 Action<T> resultHandler = delegate(T result) { |
| 429 if (medium.IsCancelled) | 419 if (medium.IsCancelled) |
| 430 return; | 420 return; |
| 431 | 421 |
| 432 var promise = chained(result); | 422 var promise = chained(result); |
| 433 | 423 |
| 438 ); | 428 ); |
| 439 | 429 |
| 440 // notify chained operation that it's not needed anymore | 430 // notify chained operation that it's not needed anymore |
| 441 // порядок вызова Then, Cancelled важен, поскольку от этого | 431 // порядок вызова Then, Cancelled важен, поскольку от этого |
| 442 // зависит IsExclusive | 432 // зависит IsExclusive |
| 443 medium.Cancelled(() => { | 433 medium.Last( |
| 444 if (promise.IsExclusive) | 434 null, |
| 445 promise.Cancel(); | 435 null, |
| 446 }); | 436 () => { |
| 437 if (promise.IsExclusive) | |
| 438 promise.Cancel(); | |
| 439 } | |
| 440 ); | |
| 447 }; | 441 }; |
| 448 | 442 |
| 449 ErrorHandler<T> errorHandler; | 443 Func<Exception,T> errorHandler; |
| 450 | 444 |
| 451 if (error != null) | 445 if (error != null) |
| 452 errorHandler = delegate(Exception e) { | 446 errorHandler = delegate(Exception e) { |
| 453 try { | 447 try { |
| 454 var promise = error(e); | 448 var promise = error(e); |
| 496 ); | 490 ); |
| 497 | 491 |
| 498 return medium; | 492 return medium; |
| 499 } | 493 } |
| 500 | 494 |
| 501 public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error) { | 495 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained, Func<Exception,IPromise<TNew>> error) { |
| 502 return Chain(chained, error, null); | 496 return Chain(chained, error, null); |
| 503 } | 497 } |
| 504 | 498 |
| 505 public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained) { | 499 public IPromise<TNew> Chain<TNew>(Func<T, IPromise<TNew>> chained) { |
| 506 return Chain(chained, null, null); | 500 return Chain(chained, null, null); |
| 507 } | 501 } |
| 508 | 502 |
| 509 public IPromise<T> Cancelled(Action handler) { | 503 public IPromise<T> Cancelled(Action handler) { |
| 510 var medium = new Promise<T>(this,true); | 504 var medium = new Promise<T>(this); |
| 511 AddHandler(null, null, handler, medium); | 505 AddHandler(null, null, handler, medium); |
| 512 return medium; | 506 return medium; |
| 513 } | 507 } |
| 514 | 508 |
| 515 /// <summary> | 509 /// <summary> |
| 583 | 577 |
| 584 public T Join() { | 578 public T Join() { |
| 585 return Join(Timeout.Infinite); | 579 return Join(Timeout.Infinite); |
| 586 } | 580 } |
| 587 | 581 |
| 588 void AddHandler(ResultHandler<T> success, ErrorHandler<T> error, Action cancel, Promise<T> medium) { | 582 void AddHandler(Action<T> success, Func<Exception,T> error, Action cancel, Promise<T> medium) { |
| 589 if (success != null || error != null) | 583 if (success != null || error != null) |
| 590 Interlocked.Increment(ref m_childrenCount); | 584 Interlocked.Increment(ref m_childrenCount); |
| 591 | 585 |
| 592 var handler = new HandlerDescriptor { | 586 var handler = new HandlerDescriptor { |
| 593 resultHandler = success, | 587 resultHandler = success, |
| 757 return p; | 751 return p; |
| 758 } | 752 } |
| 759 | 753 |
| 760 #region IPromiseBase explicit implementation | 754 #region IPromiseBase explicit implementation |
| 761 | 755 |
| 762 IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) { | 756 IPromise IPromise.Then(Action success, Action<Exception> error, Action cancel) { |
| 763 return Then( | 757 return Then( |
| 764 success != null ? new ResultHandler<T>(x => success()) : null, | 758 success != null ? new Action<T>(x => success()) : null, |
| 765 error != null ? new ErrorHandler<T>(e => { | 759 error != null ? new Func<Exception,T>(e => { |
| 766 error(e); | 760 error(e); |
| 767 return default(T); | 761 return default(T); |
| 768 }) : null, | 762 }) : null, |
| 769 cancel | 763 cancel |
| 770 ); | 764 ); |
| 771 } | 765 } |
| 772 | 766 |
| 773 IPromise IPromise.Then(Action success, ErrorHandler error) { | 767 IPromise IPromise.Then(Action success, Action<Exception> error) { |
| 774 return Then( | 768 return Then( |
| 775 success != null ? new ResultHandler<T>(x => success()) : null, | 769 success != null ? new Action<T>(x => success()) : null, |
| 776 error != null ? new ErrorHandler<T>(e => { | 770 error != null ? new Func<Exception,T>(e => { |
| 777 error(e); | 771 error(e); |
| 778 return default(T); | 772 return default(T); |
| 779 }) : null | 773 }) : null |
| 780 ); | 774 ); |
| 781 } | 775 } |
| 783 IPromise IPromise.Then(Action success) { | 777 IPromise IPromise.Then(Action success) { |
| 784 Safe.ArgumentNotNull(success, "success"); | 778 Safe.ArgumentNotNull(success, "success"); |
| 785 return Then(x => success()); | 779 return Then(x => success()); |
| 786 } | 780 } |
| 787 | 781 |
| 788 IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) { | 782 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { |
| 789 return ChainNoResult(chained, error, cancel); | 783 return ChainNoResult(chained, error, cancel); |
| 790 } | 784 } |
| 791 | 785 |
| 792 IPromise ChainNoResult(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) { | 786 IPromise ChainNoResult(Func<IPromise> chained, Func<Exception,IPromise> error, Action cancel) { |
| 793 Safe.ArgumentNotNull(chained, "chained"); | 787 Safe.ArgumentNotNull(chained, "chained"); |
| 794 | 788 |
| 795 var medium = new Promise<object>(this, true); | 789 var medium = new Promise<object>(this); |
| 796 | 790 |
| 797 ResultHandler<T> resultHandler = delegate(T result) { | 791 Action<T> resultHandler = delegate { |
| 798 if (medium.IsCancelled) | 792 if (medium.IsCancelled) |
| 799 return; | 793 return; |
| 800 | 794 |
| 801 var promise = chained(); | 795 var promise = chained(); |
| 802 | 796 |
| 813 if (promise.IsExclusive) | 807 if (promise.IsExclusive) |
| 814 promise.Cancel(); | 808 promise.Cancel(); |
| 815 }); | 809 }); |
| 816 }; | 810 }; |
| 817 | 811 |
| 818 ErrorHandler<T> errorHandler; | 812 Func<Exception,T> errorHandler; |
| 819 | 813 |
| 820 if (error != null) | 814 if (error != null) |
| 821 errorHandler = delegate(Exception e) { | 815 errorHandler = delegate(Exception e) { |
| 822 try { | 816 try { |
| 823 var promise = error(e); | 817 var promise = error(e); |
| 864 null | 858 null |
| 865 ); | 859 ); |
| 866 | 860 |
| 867 return medium; | 861 return medium; |
| 868 } | 862 } |
| 869 IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error) { | 863 IPromise IPromise.Chain(Func<IPromise> chained, Func<Exception,IPromise> error) { |
| 870 return ChainNoResult(chained, error, null); | 864 return ChainNoResult(chained, error, null); |
| 871 } | 865 } |
| 872 IPromise IPromise.Chain(Func<IPromise> chained) { | 866 IPromise IPromise.Chain(Func<IPromise> chained) { |
| 873 return ChainNoResult(chained, null, null); | 867 return ChainNoResult(chained, null, null); |
| 874 } | 868 } |
| 875 | 869 |
| 876 | 870 |
| 877 void IPromise.Last(Action success, ErrorHandler error, Action cancel) { | 871 void IPromise.Last(Action success, Action<Exception> error, Action cancel) { |
| 878 Last(x => success(), error, cancel); | 872 Last(x => success(), error, cancel); |
| 879 } | 873 } |
| 880 | 874 |
| 881 void IPromise.Last(Action success, ErrorHandler error) { | 875 void IPromise.Last(Action success, Action<Exception> error) { |
| 882 Last(x => success(), error, null); | 876 Last(x => success(), error, null); |
| 883 } | 877 } |
| 884 | 878 |
| 885 void IPromise.Last(Action success) { | 879 void IPromise.Last(Action success) { |
| 886 Last(x => success(), null, null); | 880 Last(x => success(), null, null); |
| 887 } | 881 } |
| 888 | 882 |
| 889 IPromise IPromise.Error(ErrorHandler error) { | 883 IPromise IPromise.Error(Action<Exception> error) { |
| 890 return Error(error); | 884 return Error(error); |
| 891 } | 885 } |
| 892 | 886 |
| 893 IPromise IPromise.Anyway(Action handler) { | 887 IPromise IPromise.Anyway(Action handler) { |
| 894 return Anyway(handler); | 888 return Anyway(handler); |
