-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
114 lines (101 loc) · 3.67 KB
/
Copy pathProgram.cs
File metadata and controls
114 lines (101 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace AsyncMessageHandler
{
class Program
{
static void Main(string[] args)
{
TestMessageHandler(MessageHandlingMode.Unordered);
TestMessageHandler(MessageHandlingMode.OrderedAbortAllOnAnyFailure);
TestMessageHandler(MessageHandlingMode.OrderedContinueOnAnyFailure);
Console.WriteLine();
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
private static void TestMessageHandler(MessageHandlingMode handlingMode)
{
Console.WriteLine($"===================================================");
Console.WriteLine($"Testing handling mode '{handlingMode}'");
Console.WriteLine($"===================================================");
Console.WriteLine();
try
{
var messageHandler = new MessageHandler(handlingMode, MyHandlerMethod);
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
tasks.Add(
messageHandler.HandleAsync(new Message() { MessageText = $"Message {i}" })
);
}
Task.WaitAll(tasks.ToArray());
}
catch (Exception exception)
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine($"Uncaught exception: {exception.Message}");
Console.WriteLine();
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine();
}
private static async Task MyHandlerMethod(Message message)
{
Console.WriteLine($"Processing message '{message.MessageText}'...");
await Task.Delay(500 * (new Random()).Next(1, 5));
if (message.MessageText.Contains("7")) throw new Exception("Bad number 7!");
Console.WriteLine($"Message '{message.MessageText}' processed!");
}
}
public class Message
{
public string MessageText { get; set; }
}
public interface IMessageHandler
{
Task HandleAsync(Message message);
}
public enum MessageHandlingMode
{
Unordered,
OrderedAbortAllOnAnyFailure,
OrderedContinueOnAnyFailure,
}
public class MessageHandler : IMessageHandler
{
public MessageHandler(MessageHandlingMode handlingMode, Func<Message, Task> handlerMethod)
{
HandlingMode = handlingMode;
HandlerMethod = handlerMethod;
}
private Task currentTask = Task.CompletedTask;
private readonly MessageHandlingMode HandlingMode;
private readonly Func<Message, Task> HandlerMethod;
public Task HandleAsync(Message message)
{
if (HandlingMode == MessageHandlingMode.Unordered)
{
return Task.Run(()=>HandlerMethod?.Invoke(message));
}
currentTask = new Task((state) => {
var previousTask = (Task)state;
try
{
Task.WaitAll(previousTask);
}
catch (Exception)
{
if (HandlingMode == MessageHandlingMode.OrderedAbortAllOnAnyFailure) throw;
//log or trigger an OnException event (to be implemented)
}
Task.WaitAll(HandlerMethod?.Invoke(message));
}, currentTask);
currentTask.Start();
return currentTask;
}
}
}