-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
229 lines (191 loc) · 8.3 KB
/
Program.cs
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
using System.Diagnostics;
namespace AsyncExample2
{
internal class Program
{
static readonly List<string> playList = new()
{
"Fox", "Sugar", "Squirrel", "Elephant", "Rabbit"
};
static readonly Dictionary<string, string> lyrics = new()
{
{ "Fox", "The quick brown fox" },
{ "Sugar", "The sweetest thing is sugar" },
{ "Squirrel", "Squirrels are brown or red" },
{ "Elephant", "Elephants are grey and have tusks" },
{ "Rabbit", "Rabbits are small with floppy ears" }
};
static async Task<string> TryFindLyrics(string songName)
{
return await Task.Run(() => {
Console.WriteLine($"Retrieving lyrics for {songName}");
Thread.Sleep(3000);
return Program.lyrics[songName];
});
}
static async Task<string?> TryFindSongName(string matchString)
{
foreach (string songName in playList)
{
var lyrics = await TryFindLyrics(songName);
if (lyrics.Contains(matchString))
{
Console.WriteLine($"Found song {songName} containing {matchString}");
return songName;
}
}
Console.WriteLine($"No song contains {matchString}");
return null;
}
static void FindSong(string matchString)
{
Console.WriteLine($"Creating task to search for song containing {matchString} ... ");
var findTask = Program.TryFindSongName(matchString);
Console.WriteLine($"About to await find task ... ");
var songName = findTask.GetAwaiter().GetResult();
Console.WriteLine($"Find task has returned a result!");
if (songName == null)
{
Console.WriteLine($"No song found containing {matchString}!");
}
else
{
Console.WriteLine($"Found song name {songName}");
}
}
static async Task MyWaitTask(string taskName, int milliseconds)
{
Console.WriteLine($"Task: {taskName} delaying for {milliseconds} milliseconds at {sw.ElapsedMilliseconds}");
Thread.Sleep(1000);
await Task.Delay(milliseconds).ContinueWith(
t =>
{
Console.WriteLine($"Task: {taskName} finished {milliseconds} millisecond delay at {sw.ElapsedMilliseconds}");
});
}
static Task CreateWaitTask(string taskName, int milliseconds)
{
Console.WriteLine($"StartWaitTask: creating {taskName} to sleep for {milliseconds} milliseconds at {sw.ElapsedMilliseconds}");
return Task.Run(() => MyWaitTask(taskName, milliseconds));
}
static async Task MySegmentedWaitTask()
{
const int delay = 10000;
List<Task> someTasks = new();
Console.WriteLine($"MySegmentedWaitTask starting first wait at {sw.ElapsedMilliseconds}");
someTasks.Add(Task.Delay(delay));
Console.WriteLine($"MySegmentedWaitTask starting second wait at {sw.ElapsedMilliseconds}");
someTasks.Add(Task.Delay(delay));
Console.WriteLine($"MySegmentedWaitTask starting third wait at {sw.ElapsedMilliseconds}");
someTasks.Add(Task.Delay(delay));
Console.WriteLine($"MySegmentedWaitTask starting fourth wait at {sw.ElapsedMilliseconds}");
someTasks.Add(Task.Delay(delay));
Console.WriteLine($"MySegmentedWaitTask waiting for tasks to complete at {sw.ElapsedMilliseconds}");
await Task.WhenAll(someTasks.ToArray());
Console.WriteLine($"MySegmentedWaitTask all tasks complete at {sw.ElapsedMilliseconds}");
}
static async Task MyNestedWaitTask2()
{
Console.WriteLine($"MyNestedWaitTask2 starting nested task at {sw.ElapsedMilliseconds}");
#if false
for (int i = 0; i < int.MaxnValue; ++i)
{
Console.WriteLine($"MyNestedWaitTask2 looping at {sw.ElapsedMilliseconds}");
Thread.Sleep(1000);
}
#endif
await Task.Delay(int.MaxValue);
}
static async Task MyNestedWaitTask1()
{
Console.WriteLine($"MyNestedWaitTask1 starting nested task at {sw.ElapsedMilliseconds}");
await MyNestedWaitTask2();
}
static async Task MyNestedWaitTask()
{
Console.WriteLine($"MyNestedWaitTask starting nested task at {sw.ElapsedMilliseconds}");
await MyNestedWaitTask1();
}
static readonly Stopwatch sw = Stopwatch.StartNew();
static void SecondFunction()
{
Thread.Sleep(int.MaxValue);
}
static void FirstFunction()
{
SecondFunction();
}
static void TopLevelThreadFunction()
{
int myThreadId = Thread.CurrentThread.ManagedThreadId;
int myProcessorId = Thread.GetCurrentProcessorId();
Thread.CurrentThread.Name = "TopLevelThreadFunction " + myThreadId.ToString();
FirstFunction();
}
static async Task<int> ReadIntegerFromDatabase()
{
/* .... */
await Task.Delay(10000);
return 42000;
}
static async Task<int> ReadIntegerFromDatabase2()
{
/* .... */
await Task.Delay(10000);
return 42000;
}
static async Task Main(string[] args)
{
Console.WriteLine($"main: About to read integer at {sw.ElapsedMilliseconds}");
var myTask = ReadIntegerFromDatabase();
var myTask2 = ReadIntegerFromDatabase2();
Console.WriteLine($"main: read integer returned at {sw.ElapsedMilliseconds}");
await myTask;
await myTask2;
Console.WriteLine($"main: await completed at {sw.ElapsedMilliseconds}");
int x = myTask.Result;
int y = myTask2.Result;
return;
Console.WriteLine($"main: Invoking Task.Delay at {sw.ElapsedMilliseconds}");
var a = Task.Delay(1000);
Console.WriteLine($"main: executing at {sw.ElapsedMilliseconds}");
await a;
Console.WriteLine($"main: one second Task.Delay completed at {sw.ElapsedMilliseconds}");
switch (args[0])
{
case "a":
FindSong("tusks");
break;
case "b":
List<Task> myTasks = new();
myTasks.Add(CreateWaitTask("A", 3000));
myTasks.Add(CreateWaitTask("B", 4000));
myTasks.Add(CreateWaitTask("C", 5000));
Thread.Sleep(1000);
await Task.WhenAll(myTasks);
Console.WriteLine($"All tasks complete at {sw.ElapsedMilliseconds}");
break;
case "c":
List<Thread> myThreads = new();
for (int i = 0; i < 10; ++i)
{
myThreads.Add(new Thread(TopLevelThreadFunction));
myThreads[myThreads.Count - 1].Start();
}
myThreads[0].Join();
break;
case "d":
Console.WriteLine($"main: starting MySegmentedWaitTask at {sw.ElapsedMilliseconds}");
var mytask = MySegmentedWaitTask();
Console.WriteLine($"main: MySegmentedWaitTask has been started at {sw.ElapsedMilliseconds}");
await mytask;
Console.WriteLine($"main: MySegmentedWaitTask completed at {sw.ElapsedMilliseconds}");
break;
case "e":
Console.WriteLine($"main: starting MyNestedWaitTask at {sw.ElapsedMilliseconds}");
await MyNestedWaitTask();
break;
}
}
}
}