-
-
Save binki/7bf565bb398c419958f64ebddb14634b to your computer and use it in GitHub Desktop.
Example of running all the operations concurrently
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Starting SynchronizationContext | |
0: Started | |
2: Started | |
2: Received number 1 | |
2: Received number 2 | |
2: Received number 3 | |
2: Received number 4 | |
2: Stopped | |
0: Received number 1 | |
0: Received number 2 | |
0: Received number 3 | |
0: Received number 4 | |
0: Stopped | |
1: Started | |
1: Received number 1 | |
1: Received number 2 | |
1: Received number 3 | |
3: Started | |
1: Received number 4 | |
1: Stopped | |
3: Received number 1 | |
3: Received number 2 | |
3: Received number 3 | |
3: Received number 4 | |
3: Stopped | |
SynchronizationContext finished |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("Starting SynchronizationContext"); | |
Nito.AsyncEx.AsyncContext.Run(Run); | |
Console.WriteLine("SynchronizationContext finished"); | |
} | |
// This method is run like it is a UI callback. I.e., it has a | |
// single-threaded event-loop-based synchronization context which | |
// processes asynchronous callbacks. | |
static Task Run() | |
{ | |
foreach (var i in Enumerable.Range(0, 4)) | |
{ | |
var demoOperation = new AsyncDemoUsingAsyncOperations(); | |
demoOperation.Started += (sender, e) => Console.WriteLine($"{i}: Started"); | |
demoOperation.NewNumber += (sender, e) => Console.WriteLine($"{i}: Received number {e.Num}"); | |
demoOperation.Stopped += (sender, e) => | |
{ | |
// The AsyncDemoUsingAsyncOperation has a bug where it fails to call | |
// AsyncOperation.OperationCompleted(). Do that for it. If we don’t, | |
// the AsyncContext will never exit because there are outstanding unfinished | |
// asynchronous operations. | |
((AsyncOperation)typeof(AsyncDemoUsingAsyncOperations).GetField("asyncOp", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(demoOperation)).OperationCompleted(); | |
Console.WriteLine($"{i}: Stopped"); | |
}; | |
demoOperation.Start(); | |
} | |
// AsyncContext requires us to return a Task because that is its | |
// normal use case. | |
return Nito.AsyncEx.TaskConstants.Completed; | |
} | |
} | |
class AsyncDemoUsingAsyncOperations | |
{ | |
AsyncOperation asyncOp; | |
bool isBusy; | |
void NotifyStarted() | |
{ | |
isBusy = true; | |
Started(this, new EventArgs()); | |
} | |
void NotifyStopped() | |
{ | |
isBusy = false; | |
Stopped(this, new EventArgs()); | |
} | |
public void Start() | |
{ | |
if (isBusy) | |
throw new InvalidOperationException("Already working you moron..."); | |
asyncOp = AsyncOperationManager.CreateOperation(null); | |
ThreadPool.QueueUserWorkItem(new WaitCallback(StartOperation)); | |
} | |
public event EventHandler Started = delegate { }; | |
public event EventHandler Stopped = delegate { }; | |
public event EventHandler<NewNumberEventArgs> NewNumber = delegate { }; | |
private void StartOperation(object state) | |
{ | |
asyncOp.Post(args => NotifyStarted(), null); | |
for (int i = 1; i < 5; i++) | |
asyncOp.Post(args => NewNumber(this, args as NewNumberEventArgs), new NewNumberEventArgs(i)); | |
asyncOp.Post(args => NotifyStopped(), null); | |
} | |
} | |
class NewNumberEventArgs : EventArgs | |
{ | |
public int Num { get; private set; } | |
public NewNumberEventArgs(int num) | |
{ | |
Num = num; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment