About a year ago, I blogged on using the .NET 2.0 facility SynchronizationContext to create thread-aware components which could be hosted and would "do the right thing" for callbacks. Here's the Link to that post.
Recently, I got an email from a reader who wanted to use that paradigm, but wanted to be able to suspend the operation for some period of time and then resume it later on. He asked if there was an easy way to modify the sample I presented, and it turns out that there is.
It essentially involves three steps:
1. In the AsyncStateData structure, add a ManualResetEvent object. This will be used to trigger the pause/resume behavior. It must be initially set as signaled. 2. In the actual asynchronous operation loop, add the event into the loop condition by calling event.WaitOne(). Make sure you have released any locks and the code can safely be halted at that point in the logic otherwise you may create deadlock scenarios and other difficult debugging issues. 3. Add a Pause and Continue method into the class which signals and resets the event.
1: class AsyncStateData
2: {
3: private ManualResetEvent pauseEvent = new ManualResetEvent(true);
4: ...
5: }
1: public partial class Calculator
3: private void InternalCalculatePi(int digits, AsyncStateData
4: asyncData)
5: {
6: int completedDigits = 0;
7: for (; !asyncData.canceled && pauseEvent.WaitOne(-1, true) &&
8: completedDigits < digits; completedDigits++)
9: { ... }
10: }
11:
12: ...
13: }
3: public void PauseAsync(object asyncTask)
4: {
5: AsyncStateData asyncData = asyncTask as AsyncStateData;
6: if (asyncData != null && asyncData.running == true)
7: asyncData.pauseEvent.Reset();
8: }
9:
10: public void ContinueAsync(object asyncTask)
11: {
12: AsyncStateData asyncData = asyncTask as AsyncStateData;
13: if (asyncData != null && asyncData.running == true)
14: asyncData.pauseEvent.Set();
15: }
16: ...
17: }
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.