i have some operation that sometimes i want to stop in the middle:
bool contine;
foreach (var item in this)
{
if (contine)
{
// do my stuss
}
}
The issue here that inside this foreach
sometimes i need specific delay time so i am using Thread.Sleep
. So when i stop my operation in case i am still inside this Thread.Sleep
my application is waiting until this Thread.Sleep
end and only than stop my operation so can i exit from Thread.Sleep
in the middle ?
Update
The reason i need specific sleep is because i am play packets and between every packets there is a Time stamp
so this is why i need this sleep.
You can use Task.Delay which also can be canceled.
private void Method(CancellationToken token)
{
foreach (var item in this)
{
if (!token.IsCancellationRequested)
{
// do my stuss
Task.Delay(1000, token).Wait(); // use await for async method
}
else break; // end
}
}
When you want to call
var source = new CancellationTokenSource();
Method(source.Token);
And when you want to cancel.
source.Cancel();
For those who are using Framework .Net 4.0,
I've adapted the accepted answer with the enhancement that, it can be restarted any times because TokenSource
is discarded and recreated for each call to Method(...)
.
Using Microsoft.Bcl.Async v1.0.168 for .NET Framework 4 (with KB2468871)
public CancellationTokenSource TokenSource = null;
...
await Method(TokenSource);
...
// Somewhere else, cancel the operation
TokenSource?.Cancel();
...
async void Method(CancellationTokenSource tokenSource)
{
try
{
// Create a new CancellationTokenSource each time starting the new work stuff
tokenSource = new CancellationTokenSource();
foreach (var item in this)
{
if (!tokenSource.IsCancellationRequested)
{
// Do work stuff
...
// Using await for async method to make UI responsive while waiting
await Task.Factory.StartNew(() =>
{
tokenSource.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000));
});
}
else
break;
}
finally
{
// Release the tokenSource to reuse a new one nex time method is called
tokenSource.Dispose();
}
}
Regards.
One possible solution could be to use your own Sleep
method like (needs to be improved for sure!):
/// <summary>
/// Contains extensions for threads.
/// </summary>
public static class ThreadExtensions
{
/// <summary>
/// Allows sleeping with cancellation.
/// </summary>
/// <param name="thread">The reference to the thread itself.</param>
/// <param name="sleep">The amount of time to sleep in milliseconds.</param>
/// <param name="source">An instance of <see cref="CancellationTokenSource"/> which can be used to signal the cancellation.</param>
public static void InterruptableSleep(this Thread thread, int sleep, CancellationTokenSource source)
{
while (!source.IsCancellationRequested && (sleep -= 5) > 0)
{
Thread.Sleep(5);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.