You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

99 lines
3.0 KiB

  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using MQTTnet.Internal;
  6. namespace MQTTnet.Tests
  7. {
  8. [TestClass]
  9. public class AsyncLock_Tests
  10. {
  11. [TestMethod]
  12. public async Task Lock_Serial_Calls()
  13. {
  14. var sum = 0;
  15. var @lock = new AsyncLock();
  16. for (var i = 0; i < 100; i++)
  17. {
  18. using (await @lock.WaitAsync(CancellationToken.None).ConfigureAwait(false))
  19. {
  20. sum++;
  21. }
  22. }
  23. Assert.AreEqual(100, sum);
  24. }
  25. [TestMethod]
  26. [ExpectedException(typeof(TaskCanceledException))]
  27. public async Task Test_Cancellation()
  28. {
  29. var @lock = new AsyncLock();
  30. // This call will never "release" the lock due to missing _using_.
  31. await @lock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
  32. using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
  33. {
  34. await @lock.WaitAsync(cts.Token).ConfigureAwait(false);
  35. }
  36. }
  37. //[TestMethod]
  38. //public async Task Test_Cancellation_With_Later_Access()
  39. //{
  40. // var @lock = new AsyncLock();
  41. // var releaser = await @lock.WaitAsync().ConfigureAwait(false);
  42. // try
  43. // {
  44. // using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
  45. // {
  46. // await @lock.WaitAsync(cts.Token).ConfigureAwait(false);
  47. // }
  48. // }
  49. // catch (OperationCanceledException)
  50. // {
  51. // }
  52. // releaser.Dispose();
  53. // using (await @lock.WaitAsync().ConfigureAwait(false))
  54. // {
  55. // // When the method finished, the thread got access.
  56. // }
  57. //}
  58. [TestMethod]
  59. public void Lock_10_Parallel_Tasks()
  60. {
  61. const int ThreadsCount = 10;
  62. var threads = new Task[ThreadsCount];
  63. var @lock = new AsyncLock();
  64. var globalI = 0;
  65. for (var i = 0; i < ThreadsCount; i++)
  66. {
  67. #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
  68. threads[i] = Task.Run(async () =>
  69. {
  70. using (var releaser = await @lock.WaitAsync(CancellationToken.None))
  71. {
  72. var localI = globalI;
  73. await Task.Delay(10); // Increase the chance for wrong data.
  74. localI++;
  75. globalI = localI;
  76. }
  77. });
  78. #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
  79. }
  80. Task.WaitAll(threads);
  81. Assert.AreEqual(ThreadsCount, globalI);
  82. }
  83. }
  84. }