├── .gitattributes
├── .gitignore
├── AsyncAwaitPitfalls
├── App.config
├── App.xaml
├── App.xaml.cs
├── AsyncAwaitPitfalls.csproj
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── README.md
├── TaskTests.cs
└── obj
│ └── Debug
│ ├── journeyofcode.AsyncAwaitPitfalls_MarkupCompile.i.cache
│ ├── journeyofcode.AsyncAwaitPitfalls_MarkupCompile.i.lref
│ ├── journeyofcode.AsyncAwaitPitfalls_MarkupCompile.lref
│ └── journeyofcode.TaskTests_MarkupCompile.i.cache
├── BlinkingClock
├── example.html
└── jquery.clock.js
├── GCUnitTests
├── GCUnitTests.sln
└── GCUnitTests
│ ├── FooTests.cs
│ ├── GCUnitTests.csproj
│ ├── GCWatch.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── packages.config
├── JavaSnippets
├── .classpath
├── .project
├── README.md
└── src
│ ├── snippet00
│ └── Foo.java
│ ├── snippet01
│ └── Foo.java
│ ├── snippet02
│ └── Foo.java
│ ├── snippet03
│ └── Foo.java
│ ├── snippet04
│ └── Foo.java
│ ├── snippet05
│ └── Foo.java
│ ├── snippet06
│ └── Foo.java
│ ├── snippet07
│ └── Foo.java
│ ├── snippet08
│ └── Foo.java
│ ├── snippet09
│ └── Program.java
│ ├── snippet10
│ └── Foo.java
│ ├── snippet11
│ └── Foo.java
│ └── snippet12
│ └── Foo.java
├── LICENSE
├── OnenoteOCR
├── OnenoteOCR.sln
├── TestApplication
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── TestApplication.csproj
├── journeyofcode.Images.OnenoteOCR.nupkg
│ └── journeyofcode.Images.OnenoteOCR.nupkg.nuproj
└── journeyofcode.Images.OnenoteOCR
│ ├── IOcrEngine.cs
│ ├── OcrException.cs
│ ├── OnenoteOcrEngine.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── journeyofcode.Images.OnenoteOCR.csproj
├── README.md
├── SingleThreadScheduler
├── SingleThreadScheduler.Tests
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── SingleThreadScheduler.Tests.csproj
│ ├── SingleThreadTaskSchedulerTests.cs
│ ├── TaskLazyTests.cs
│ └── packages.config
├── SingleThreadScheduler.sln
├── SingleThreadScheduler
│ ├── App.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── SingleThreadScheduler.csproj
│ ├── SingleThreadTaskScheduler.cs
│ ├── TaskFactoryExtensions.cs
│ └── TaskLazy.cs
└── journeyofcode.Threading.SingleThreadScheduler.nupkg
│ └── journeyofcode.Threading.SingleThreadScheduler.nupkg.nuproj
└── log4j2args4j
├── pom.xml
└── src
└── main
├── java
└── com
│ └── journeyofcode
│ └── log4j2args4j
│ ├── Parameters.java
│ └── Program.java
└── resources
└── log4j2.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #==== VISUAL STUDIO IGNORES ====
2 | #Property files
3 | *.suo
4 | *.user
5 | #Binary directories
6 | /*/*/bin
7 | /*/*/obj
8 | #Nuget packages
9 | /*/packages
10 |
11 | #==== ECLIPSE IGNORES ====
12 | /*/bin
13 | /*/.settings
14 | /.metadata
15 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Windows;
4 |
5 | namespace journeyofcode.AsyncAwaitPitfalls
6 | {
7 | ///
8 | /// Interaction logic for App.xaml
9 | ///
10 | public partial class App : Application
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/AsyncAwaitPitfalls.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {BBF53862-564D-4A62-8AB0-AA8E39231D75}
8 | WinExe
9 | Properties
10 | journeyofcode.AsyncAwaitPitfalls
11 | journeyofcode.AsyncAwaitPitfalls
12 | v4.5.1
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | 4.0
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | MSBuild:Compile
55 | Designer
56 |
57 |
58 |
59 | MSBuild:Compile
60 | Designer
61 |
62 |
63 | App.xaml
64 | Code
65 |
66 |
67 | MainWindow.xaml
68 | Code
69 |
70 |
71 |
72 |
73 | Code
74 |
75 |
76 | True
77 | True
78 | Resources.resx
79 |
80 |
81 | True
82 | Settings.settings
83 | True
84 |
85 |
86 | ResXFileCodeGenerator
87 | Resources.Designer.cs
88 |
89 |
90 | SettingsSingleFileGenerator
91 | Settings.Designer.cs
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
106 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 |
6 | namespace journeyofcode.AsyncAwaitPitfalls
7 | {
8 | ///
9 | /// Interaction logic for MainWindow.xaml
10 | ///
11 | public partial class MainWindow : Window
12 | {
13 | public MainWindow()
14 | {
15 | InitializeComponent();
16 |
17 | var tester = new Tests();
18 |
19 | this.DataContext = new[]
20 | {
21 | new Item{ Name = "Simple call", Action = () => tester.SimpleCallFromAsync()},
22 | new Item{ Name = "ThreadPool.QueueUserWorkItem", Action = () => tester.ThreadPool_QueueUserWorkItem()},
23 | new Item{ Name = "Task.Factory.StartNew", Action = () => tester.TaskFactory()},
24 | new Item{ Name = "Task.Run", Action = () => tester.TaskRun()},
25 |
26 | new Item{ Name = "Continue with", Action = () => tester.ContinueWith()},
27 | new Item{ Name = "Continue with (TaskScheduler)", Action = () => tester.ContinueWith2()},
28 |
29 | new Item{ Name = "StartNew with TaskScheduler", Action = () => tester.TaskScheduler_FromCurrentSynchronizationContext()},
30 | new Item{ Name = "StartNew with hidden TaskScheduler", Action = () => tester.TaskScheduler_HiddenScheduler()},
31 |
32 | new Item{ Name = "Plain Await", Action = () => tester.UsingAwait()},
33 | new Item{ Name = "Configuring Awaiter", Action = () => tester.ConfiguringAwaiter()},
34 | new Item{ Name = "Configuring Awaiter with short action", Action = () => tester.ConfiguringAwaiter2()},
35 |
36 | new Item{ Name = "Calling an async method (the wrong way)", Action = () => tester.CallingAsyncWrong()},
37 | new Item{ Name = "Calling an async method (the right way)", Action = () => tester.CallingAsyncRight()},
38 |
39 | new Item{ Name = "async and ContinueWith", Action = () => tester.AsyncAndContinueWith()},
40 | new Item{ Name = "Nested Tasks", Action = () => tester.NestedTask()},
41 | new Item{ Name = "Avoid Nested Tasks", Action = () => tester.AvoidNestedTasks()},
42 |
43 | new Item{ Name = "Don't block", Action = () => tester.DontBlock()},
44 | new Item{ Name = "Deadlock", Action = () => tester.Deadlock()},
45 |
46 | new Item{ Name = "Final example", Action = () => tester.FinalExample()},
47 | };
48 | }
49 |
50 | private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
51 | {
52 | ((Action) ((Button) sender).Tag)();
53 | }
54 | }
55 |
56 | public class Item
57 | {
58 | public string Name { get; set; }
59 | public Action Action { get; set; }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Runtime.InteropServices;
4 | using System.Windows;
5 |
6 | [assembly: AssemblyTitle("AsyncAwaitPitfalls")]
7 | [assembly: AssemblyDescription("")]
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("Matthias Welz")]
10 | [assembly: AssemblyProduct("journeyofcode.com")]
11 | [assembly: AssemblyCopyright("Copyright © Matthias Welz 2014")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | [assembly: ComVisible(false)]
16 | [assembly: CLSCompliant(true)]
17 |
18 | [assembly: AssemblyVersion("1.0.*")]
19 |
20 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
21 |
22 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34014
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace journeyofcode.AsyncAwaitPitfalls.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("journeyofcode.AsyncAwaitPitfalls.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.34014
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace journeyofcode.AsyncAwaitPitfalls.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/README.md:
--------------------------------------------------------------------------------
1 | # Will it block? Debunking async/await pitfalls
2 |
3 | [Visit the article](http://www.journeyofcode.com/will-block-debunking-asyncawait-pitfalls/).
4 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/TaskTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace journeyofcode.AsyncAwaitPitfalls
7 | {
8 | public sealed class Tests
9 | {
10 | private readonly Thread _uiThread;
11 |
12 | public Tests()
13 | {
14 | this._uiThread = Thread.CurrentThread;
15 | }
16 |
17 | private void PrintInfo(string marker)
18 | {
19 | var currentThread = Thread.CurrentThread == this._uiThread ? "UI Thread" : "Threadpool Thread";
20 |
21 | Console.WriteLine("{0} ({1})", marker, currentThread);
22 | }
23 |
24 | public async void SimpleCallFromAsync()
25 | {
26 | //UI Thread
27 | this.PrintInfo("SimpleCall");
28 | }
29 |
30 | public void ThreadPool_QueueUserWorkItem()
31 | {
32 | //Background Thread
33 | ThreadPool.QueueUserWorkItem(o => this.PrintInfo("ThreadPool"));
34 | }
35 |
36 | public void TaskFactory()
37 | {
38 | //Background Thread *
39 | //(* when not called from within a Task)
40 | Task.Factory.StartNew(() => this.PrintInfo("TaskFactory 0"));
41 | }
42 |
43 | public void TaskScheduler_FromCurrentSynchronizationContext()
44 | {
45 | //UI Thread
46 | this.PrintInfo("0");
47 |
48 | Task.Factory.StartNew(() =>
49 | {
50 | //UI Thread
51 | this.PrintInfo("1");
52 |
53 | //UI Thread
54 | Task.Factory.StartNew(() => this.PrintInfo("3"));
55 |
56 | }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
57 | }
58 |
59 | public void TaskScheduler_HiddenScheduler()
60 | {
61 | this.PrintInfo("0");
62 |
63 | Task.Factory.StartNew(() =>
64 | {
65 | //UI Thread
66 | this.PrintInfo("1");
67 |
68 | //Background Thread
69 | Task.Factory.StartNew(() => this.PrintInfo("3"));
70 |
71 | }, CancellationToken.None, TaskCreationOptions.HideScheduler, TaskScheduler.FromCurrentSynchronizationContext());
72 | }
73 |
74 | public void TaskRun()
75 | {
76 | //Background thread
77 | Task.Run(() => this.PrintInfo("0"));
78 | }
79 |
80 | public void ContinueWith()
81 | {
82 | //Background thread *
83 | //(* when not called from within a Task)
84 | Task.Run(() => this.PrintInfo("0")).ContinueWith(task => this.PrintInfo("1"));
85 | }
86 |
87 | public void ContinueWith2()
88 | {
89 | //UI thread
90 | Task.Run(() => this.PrintInfo("0")).ContinueWith(task => this.PrintInfo("1"), TaskScheduler.FromCurrentSynchronizationContext());
91 | }
92 |
93 | public async void UsingAwait()
94 | {
95 | //UI Thread
96 | this.PrintInfo("0");
97 |
98 | //Background Thread
99 | await Task.Run(() => this.PrintInfo("1"));
100 |
101 | //UI Thread
102 | this.PrintInfo("2");
103 | }
104 |
105 | public async void ConfiguringAwaiter()
106 | {
107 | //UI Thread
108 | this.PrintInfo("0");
109 |
110 | await Task.Delay(500).ConfigureAwait(false);
111 |
112 | //Background Thread
113 | this.PrintInfo("1");
114 |
115 | await Task.Delay(500);
116 |
117 | //Background Thread
118 | this.PrintInfo("2");
119 | }
120 |
121 | public async void ConfiguringAwaiter2()
122 | {
123 | //UI Thread
124 | this.PrintInfo("0");
125 |
126 | await Task.Delay(0).ConfigureAwait(false);
127 |
128 | //UI thread
129 | this.PrintInfo("1");
130 |
131 | await Task.Delay(0);
132 |
133 | //UI thread
134 | this.PrintInfo("2");
135 | }
136 |
137 | public void CallingAsyncWrong()
138 | {
139 | this.PrintInfo("0");
140 |
141 | this.Other();
142 |
143 | this.PrintInfo("3");
144 | }
145 |
146 |
147 | public async void CallingAsyncRight()
148 | {
149 | this.PrintInfo("0");
150 |
151 | await this.Other();
152 |
153 | this.PrintInfo("3");
154 | }
155 |
156 | public void AsyncAndContinueWith()
157 | {
158 | this.PrintInfo("0");
159 |
160 | this.Other().ContinueWith(task => this.PrintInfo("3"));
161 |
162 | this.PrintInfo("4");
163 | }
164 |
165 | public async void NestedTask()
166 | {
167 | this.PrintInfo("0");
168 |
169 | //0 - 4 - 1 - 3 - 2
170 | await Task.Factory.StartNew(() => this.Other());
171 |
172 | this.PrintInfo("4");
173 | }
174 |
175 | public async void AvoidNestedTasks()
176 | {
177 | this.PrintInfo("0");
178 |
179 | await await Task.Factory.StartNew(() => this.Other());
180 | await Task.Factory.StartNew(() => this.Other()).Unwrap();
181 | await Task.Run(() => this.Other());
182 |
183 | this.PrintInfo("4");
184 | }
185 |
186 | private async Task Other()
187 | {
188 | this.PrintInfo("1");
189 |
190 | await Task.Delay(500);
191 |
192 | this.PrintInfo("2");
193 | }
194 |
195 | public void DontBlock()
196 | {
197 | this.PrintInfo("1");
198 |
199 | var result = Task.Run(() =>
200 | {
201 | Thread.Sleep(5000);
202 |
203 | return 42;
204 | }).Result;
205 |
206 | this.PrintInfo("2");
207 | }
208 |
209 | public void Deadlock()
210 | {
211 | this.PrintInfo("1");
212 |
213 | var result = this.deadlock().Result;
214 |
215 | this.PrintInfo("2");
216 | }
217 |
218 | private async Task deadlock()
219 | {
220 | var a = await Task.Run(() => "A");
221 | var b = await Task.Run(() => "B");
222 |
223 | return a + b;
224 | }
225 |
226 | public string UIProperty { get; set; }
227 |
228 | public async void FinalExample()
229 | {
230 | //Access the UI from the UI thread
231 | this.UIProperty = "Starting...";
232 |
233 | //Do some work (in background, without blocking the UI thread)
234 | await Task.Run(() => Thread.Sleep(5000));
235 |
236 | //Access the UI from the UI thread
237 | this.UIProperty = "Almost done!";
238 |
239 | //Do some work (in background, without blocking the UI thread)
240 | await Task.Run(() => Thread.Sleep(5000));
241 |
242 | //Access the UI from the UI thread
243 | this.UIProperty = "Done";
244 | }
245 | }
246 | }
247 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/obj/Debug/journeyofcode.AsyncAwaitPitfalls_MarkupCompile.i.cache:
--------------------------------------------------------------------------------
1 | journeyofcode.AsyncAwaitPitfalls
2 |
3 |
4 | winexe
5 | C#
6 | .cs
7 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\obj\Debug\
8 | journeyofcode.AsyncAwaitPitfalls
9 | none
10 | false
11 | DEBUG;TRACE
12 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\App.xaml
13 | 11151548125
14 |
15 | 10-373995933
16 | 12-114506869
17 | MainWindow.xaml;
18 |
19 | True
20 |
21 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/obj/Debug/journeyofcode.AsyncAwaitPitfalls_MarkupCompile.i.lref:
--------------------------------------------------------------------------------
1 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\obj\Debug\GeneratedInternalTypeHelper.g.i.cs
2 |
3 | FD:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\MainWindow.xaml;;
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/obj/Debug/journeyofcode.AsyncAwaitPitfalls_MarkupCompile.lref:
--------------------------------------------------------------------------------
1 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\obj\Debug\GeneratedInternalTypeHelper.g.cs
2 |
3 | FD:\Workspace\GitHub\journeyofcode\AsyncAwaitPitfalls\MainWindow.xaml;;
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAwaitPitfalls/obj/Debug/journeyofcode.TaskTests_MarkupCompile.i.cache:
--------------------------------------------------------------------------------
1 | journeyofcode.TaskTests
2 |
3 |
4 | winexe
5 | C#
6 | .cs
7 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitDatabinding\TaskTests\obj\Debug\
8 | journeyofcode.AsyncAwaitPitfalls
9 | none
10 | false
11 | DEBUG;TRACE
12 | D:\Workspace\GitHub\journeyofcode\AsyncAwaitDatabinding\TaskTests\App.xaml
13 | 11151548125
14 |
15 | 10-373995933
16 | 12-114506869
17 | MainWindow.xaml;
18 |
19 | False
20 |
21 |
--------------------------------------------------------------------------------
/BlinkingClock/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Blinking clock example
5 |
6 |
7 |
8 |
9 |
10 | Blinking clock:
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/BlinkingClock/jquery.clock.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | "use strict";
3 |
4 | function getTime() {
5 | //Credits to Raj: http://stackoverflow.com/a/12612778/232175
6 | return new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
7 | }
8 |
9 | $.fn.clock = function() {
10 | var $this = $(this);
11 | var tick = function() {
12 | //Stop all animations
13 | $this.stop(true, true);
14 |
15 | //Refresh time
16 | var time = getTime();
17 | $this.text(time);
18 |
19 | //Fadein + fadeout
20 | $this.fadeIn(500, function() {
21 | $this.fadeOut(500);
22 | });
23 | }
24 |
25 | //Hide clock initially
26 | $this.fadeOut(0);
27 | //Start timer
28 | setInterval(tick, 1000);
29 | //Do first tick now
30 | tick();
31 | }
32 | }(jQuery));
--------------------------------------------------------------------------------
/GCUnitTests/GCUnitTests.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GCUnitTests", "GCUnitTests\GCUnitTests.csproj", "{6A726385-8385-4F47-8248-8085A5109AA1}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {6A726385-8385-4F47-8248-8085A5109AA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {6A726385-8385-4F47-8248-8085A5109AA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {6A726385-8385-4F47-8248-8085A5109AA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {6A726385-8385-4F47-8248-8085A5109AA1}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/GCUnitTests/GCUnitTests/FooTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using NUnit.Framework;
5 |
6 | namespace GCUnitTests
7 | {
8 | [TestFixture]
9 | public class FooTests
10 | {
11 | [Test]
12 | public void Usable_Reference_Keeps_Object_Alive()
13 | {
14 | var obj = new Object();
15 | var gcTester = new GCWatch(obj);
16 |
17 | Assert.IsFalse(gcTester.IsEligibleForGC());
18 |
19 | GC.KeepAlive(obj);
20 | }
21 |
22 | [Test]
23 | public void No_Reference_Allows_GC()
24 | {
25 | var obj = new Object();
26 | var gcTester = new GCWatch(obj);
27 |
28 | obj = null;
29 |
30 | Assert.IsTrue(gcTester.IsEligibleForGC());
31 | }
32 |
33 | [Test]
34 | public void GC_Collects_Graph()
35 | {
36 | var foo1 = new Foo();
37 | var foo2 = new Foo();
38 |
39 | var gcTester1 = new GCWatch(foo1);
40 | var gcTester2 = new GCWatch(foo2);
41 |
42 | foo1.objects.Add(foo2);
43 | foo2.objects.Add(foo1);
44 |
45 | foo1 = null;
46 | Assert.IsFalse(gcTester1.IsEligibleForGC());
47 | Assert.IsFalse(gcTester2.IsEligibleForGC());
48 | GC.KeepAlive(foo2);
49 |
50 | foo2 = null;
51 | Assert.IsTrue(gcTester1.IsEligibleForGC());
52 | Assert.IsTrue(gcTester2.IsEligibleForGC());
53 | }
54 |
55 | [Test]
56 | public void Reference_Keeps_Object_Alive_Or_Not()
57 | {
58 | var obj = new Object();
59 | var gcTester = new GCWatch(obj);
60 |
61 | #if DEBUG
62 | Assert.IsFalse(gcTester.IsEligibleForGC());
63 | #else
64 | Assert.IsTrue(gcTester.IsEligibleForGC());
65 | #endif
66 | }
67 |
68 | [Test]
69 | public void Two_Collections_Are_Required()
70 | {
71 | var foo = new Foo();
72 | var bar = new Bar();
73 | bar.objects.Add(foo);
74 |
75 | var weakReference = new WeakReference(foo, true);
76 | foo = null;
77 | bar = null;
78 |
79 | Assert.IsTrue(weakReference.IsAlive);
80 |
81 | GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
82 |
83 | //At this point, bar has been collected, but placed into the FReachable queue. Thus, foo is still accessible (from the finalizer of foo)
84 | //Note: Might also be false (when additional, non-forced GC has occured - very unlikely, however)
85 | Assert.IsTrue(weakReference.IsAlive);
86 |
87 | GC.WaitForPendingFinalizers();
88 | GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
89 |
90 | //Now that bar has been completely collected, foo could also be collected
91 | Assert.IsFalse(weakReference.IsAlive);
92 | }
93 | }
94 |
95 | public class Foo
96 | {
97 | public List