InnerUnitOfWorkCompleteHandle.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Threading.Tasks;
  4. namespace Abp.Domain.Uow
  5. {
  6. /// <summary>
  7. /// This handle is used for innet unit of work scopes.
  8. /// A inner unit of work scope actually uses outer unit of work scope
  9. /// and has no effect on <see cref="IUnitOfWorkCompleteHandle.Complete"/> call.
  10. /// But if it's not called, an exception is thrown at end of the UOW to rollback the UOW.
  11. /// </summary>
  12. internal class InnerUnitOfWorkCompleteHandle : IUnitOfWorkCompleteHandle
  13. {
  14. public const string DidNotCallCompleteMethodExceptionMessage = "Did not call Complete method of a unit of work.";
  15. private volatile bool _isCompleteCalled;
  16. private volatile bool _isDisposed;
  17. public void Complete()
  18. {
  19. _isCompleteCalled = true;
  20. }
  21. public Task CompleteAsync()
  22. {
  23. _isCompleteCalled = true;
  24. return Task.FromResult(0);
  25. }
  26. public void Dispose()
  27. {
  28. if (_isDisposed)
  29. {
  30. return;
  31. }
  32. _isDisposed = true;
  33. if (!_isCompleteCalled)
  34. {
  35. if (HasException())
  36. {
  37. return;
  38. }
  39. throw new AbpException(DidNotCallCompleteMethodExceptionMessage);
  40. }
  41. }
  42. private static bool HasException()
  43. {
  44. try
  45. {
  46. return Marshal.GetExceptionCode() != 0;
  47. }
  48. catch (Exception)
  49. {
  50. return false;
  51. }
  52. }
  53. }
  54. }