Long running operation with timeout
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
I have a long running operation that I need to wait for or timeout.
I have working code, but I would like your opinion on improving it.
public bool RegisterEquipmentListUpdate(int ID)
if (Authentication.CheckSession(Session))
var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient();
try
bool timeout = false;
DateTime start = DateTime.Now;
//loop as long as the time isn't reached (600 seconds)
while (!timeout)
if (wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID))
wcfmonitoring.Close();
//sleep before returning true, this is set so the importer can finish multiple files without the client refreshing on the first one
Thread.Sleep(2000);
return true;
else
//sleep for 10 seconds before trying again
Thread.Sleep(10000);
//if the elapsed time is more than 10 minutes return false
if (start < DateTime.Now.AddSeconds(-600))
wcfmonitoring.Close();
return false;
catch
wcfmonitoring.Abort();
//return false in case of error
return false;
c# timeout
add a comment |Â
up vote
2
down vote
favorite
I have a long running operation that I need to wait for or timeout.
I have working code, but I would like your opinion on improving it.
public bool RegisterEquipmentListUpdate(int ID)
if (Authentication.CheckSession(Session))
var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient();
try
bool timeout = false;
DateTime start = DateTime.Now;
//loop as long as the time isn't reached (600 seconds)
while (!timeout)
if (wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID))
wcfmonitoring.Close();
//sleep before returning true, this is set so the importer can finish multiple files without the client refreshing on the first one
Thread.Sleep(2000);
return true;
else
//sleep for 10 seconds before trying again
Thread.Sleep(10000);
//if the elapsed time is more than 10 minutes return false
if (start < DateTime.Now.AddSeconds(-600))
wcfmonitoring.Close();
return false;
catch
wcfmonitoring.Abort();
//return false in case of error
return false;
c# timeout
have you considered async/await
â Nkosi
Mar 2 at 12:45
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I have a long running operation that I need to wait for or timeout.
I have working code, but I would like your opinion on improving it.
public bool RegisterEquipmentListUpdate(int ID)
if (Authentication.CheckSession(Session))
var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient();
try
bool timeout = false;
DateTime start = DateTime.Now;
//loop as long as the time isn't reached (600 seconds)
while (!timeout)
if (wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID))
wcfmonitoring.Close();
//sleep before returning true, this is set so the importer can finish multiple files without the client refreshing on the first one
Thread.Sleep(2000);
return true;
else
//sleep for 10 seconds before trying again
Thread.Sleep(10000);
//if the elapsed time is more than 10 minutes return false
if (start < DateTime.Now.AddSeconds(-600))
wcfmonitoring.Close();
return false;
catch
wcfmonitoring.Abort();
//return false in case of error
return false;
c# timeout
I have a long running operation that I need to wait for or timeout.
I have working code, but I would like your opinion on improving it.
public bool RegisterEquipmentListUpdate(int ID)
if (Authentication.CheckSession(Session))
var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient();
try
bool timeout = false;
DateTime start = DateTime.Now;
//loop as long as the time isn't reached (600 seconds)
while (!timeout)
if (wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID))
wcfmonitoring.Close();
//sleep before returning true, this is set so the importer can finish multiple files without the client refreshing on the first one
Thread.Sleep(2000);
return true;
else
//sleep for 10 seconds before trying again
Thread.Sleep(10000);
//if the elapsed time is more than 10 minutes return false
if (start < DateTime.Now.AddSeconds(-600))
wcfmonitoring.Close();
return false;
catch
wcfmonitoring.Abort();
//return false in case of error
return false;
c# timeout
edited Mar 3 at 23:47
Alexandru ClonÃÂea
1235
1235
asked Mar 2 at 12:27
Raskolnikov
367517
367517
have you considered async/await
â Nkosi
Mar 2 at 12:45
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44
add a comment |Â
have you considered async/await
â Nkosi
Mar 2 at 12:45
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44
have you considered async/await
â Nkosi
Mar 2 at 12:45
have you considered async/await
â Nkosi
Mar 2 at 12:45
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
1
down vote
This is a rough draft, since I do not know the overall picture of your project. Some design might be improved to not even use this code (events, semaphores, mutexes, and other more predictable synchronization mechanisms). I rarely use this pattern for code that I control, more for code I cannot that I know is blocking. This approach is risky, as it can lead to undesired state and data loss. You have been warned! (http://thedailywtf.com/articles/My-Tales) for reference!)
If you stay on this path, I recommend A separate class/method be responsible for this sort of behaviour, to favour reuse, this also includes the possibility of having a CancellationToken passed in, just in case you change your mind about the request:
public async Task<T> WaitForActionCompletionOrTimeout<T>(Func<T> action, int timeout, CancellationToken? globalCancellation = null)
var result = default(T); //return default for error
var localCancellation = new CancellationTokenSource();
var localAndGlobalCancellation =
CancellationTokenSource.CreateLinkedTokenSource(localCancellation.Token,
globalCancellation.HasValue ?
globalCancellation.Value :
CancellationToken.None);
Task cancelationTask = null;
Task actionTask = null;
try
cancelationTask = Task.Delay(timeout, localAndGlobalCancellation);
actionTask = Task.Factory.StartNew(() =>
result = action.Invoke();
, localAndGlobalCancellation);
catch (Exception ex)
Trace.WriteLine(ex.Message);
localCancellation.Cancel();
return null;
await Task.WhenAny(actionTask, cancelationTask).ContinueWith(t => localCancellation.Cancel());
return result;
Change the work method to return true or false, something like:
public bool CheckForUpdate()
using (var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient())
var sw = new SpinWait();
while (!wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID)) //maybe something shorter would work :) some variables are nice for debugging
sw.SpinOnce(); //magic Thread.Sleep(5) replacement with lots of goodies :) nice class to look at
Thread.Sleep(2000); //for the importer
return true;
And then:
var success = WaitForActionCompletionOrTimeout(() => CheckForUpdate, 600000 ); //I would so like 6.minutes.in.miliseconds.... ah dreams
This sort of approach (cancelling the worker) could also be done with threads in a much shorter and brute-forcier way for a slow performance increase in case of very low timeouts.
I would also advise using using and if WcfMonitoring is not IDisposable, to make it IDisposable.
One more question: What is the intent/difference between calling Abort and Close in your code?
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
This is a rough draft, since I do not know the overall picture of your project. Some design might be improved to not even use this code (events, semaphores, mutexes, and other more predictable synchronization mechanisms). I rarely use this pattern for code that I control, more for code I cannot that I know is blocking. This approach is risky, as it can lead to undesired state and data loss. You have been warned! (http://thedailywtf.com/articles/My-Tales) for reference!)
If you stay on this path, I recommend A separate class/method be responsible for this sort of behaviour, to favour reuse, this also includes the possibility of having a CancellationToken passed in, just in case you change your mind about the request:
public async Task<T> WaitForActionCompletionOrTimeout<T>(Func<T> action, int timeout, CancellationToken? globalCancellation = null)
var result = default(T); //return default for error
var localCancellation = new CancellationTokenSource();
var localAndGlobalCancellation =
CancellationTokenSource.CreateLinkedTokenSource(localCancellation.Token,
globalCancellation.HasValue ?
globalCancellation.Value :
CancellationToken.None);
Task cancelationTask = null;
Task actionTask = null;
try
cancelationTask = Task.Delay(timeout, localAndGlobalCancellation);
actionTask = Task.Factory.StartNew(() =>
result = action.Invoke();
, localAndGlobalCancellation);
catch (Exception ex)
Trace.WriteLine(ex.Message);
localCancellation.Cancel();
return null;
await Task.WhenAny(actionTask, cancelationTask).ContinueWith(t => localCancellation.Cancel());
return result;
Change the work method to return true or false, something like:
public bool CheckForUpdate()
using (var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient())
var sw = new SpinWait();
while (!wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID)) //maybe something shorter would work :) some variables are nice for debugging
sw.SpinOnce(); //magic Thread.Sleep(5) replacement with lots of goodies :) nice class to look at
Thread.Sleep(2000); //for the importer
return true;
And then:
var success = WaitForActionCompletionOrTimeout(() => CheckForUpdate, 600000 ); //I would so like 6.minutes.in.miliseconds.... ah dreams
This sort of approach (cancelling the worker) could also be done with threads in a much shorter and brute-forcier way for a slow performance increase in case of very low timeouts.
I would also advise using using and if WcfMonitoring is not IDisposable, to make it IDisposable.
One more question: What is the intent/difference between calling Abort and Close in your code?
add a comment |Â
up vote
1
down vote
This is a rough draft, since I do not know the overall picture of your project. Some design might be improved to not even use this code (events, semaphores, mutexes, and other more predictable synchronization mechanisms). I rarely use this pattern for code that I control, more for code I cannot that I know is blocking. This approach is risky, as it can lead to undesired state and data loss. You have been warned! (http://thedailywtf.com/articles/My-Tales) for reference!)
If you stay on this path, I recommend A separate class/method be responsible for this sort of behaviour, to favour reuse, this also includes the possibility of having a CancellationToken passed in, just in case you change your mind about the request:
public async Task<T> WaitForActionCompletionOrTimeout<T>(Func<T> action, int timeout, CancellationToken? globalCancellation = null)
var result = default(T); //return default for error
var localCancellation = new CancellationTokenSource();
var localAndGlobalCancellation =
CancellationTokenSource.CreateLinkedTokenSource(localCancellation.Token,
globalCancellation.HasValue ?
globalCancellation.Value :
CancellationToken.None);
Task cancelationTask = null;
Task actionTask = null;
try
cancelationTask = Task.Delay(timeout, localAndGlobalCancellation);
actionTask = Task.Factory.StartNew(() =>
result = action.Invoke();
, localAndGlobalCancellation);
catch (Exception ex)
Trace.WriteLine(ex.Message);
localCancellation.Cancel();
return null;
await Task.WhenAny(actionTask, cancelationTask).ContinueWith(t => localCancellation.Cancel());
return result;
Change the work method to return true or false, something like:
public bool CheckForUpdate()
using (var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient())
var sw = new SpinWait();
while (!wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID)) //maybe something shorter would work :) some variables are nice for debugging
sw.SpinOnce(); //magic Thread.Sleep(5) replacement with lots of goodies :) nice class to look at
Thread.Sleep(2000); //for the importer
return true;
And then:
var success = WaitForActionCompletionOrTimeout(() => CheckForUpdate, 600000 ); //I would so like 6.minutes.in.miliseconds.... ah dreams
This sort of approach (cancelling the worker) could also be done with threads in a much shorter and brute-forcier way for a slow performance increase in case of very low timeouts.
I would also advise using using and if WcfMonitoring is not IDisposable, to make it IDisposable.
One more question: What is the intent/difference between calling Abort and Close in your code?
add a comment |Â
up vote
1
down vote
up vote
1
down vote
This is a rough draft, since I do not know the overall picture of your project. Some design might be improved to not even use this code (events, semaphores, mutexes, and other more predictable synchronization mechanisms). I rarely use this pattern for code that I control, more for code I cannot that I know is blocking. This approach is risky, as it can lead to undesired state and data loss. You have been warned! (http://thedailywtf.com/articles/My-Tales) for reference!)
If you stay on this path, I recommend A separate class/method be responsible for this sort of behaviour, to favour reuse, this also includes the possibility of having a CancellationToken passed in, just in case you change your mind about the request:
public async Task<T> WaitForActionCompletionOrTimeout<T>(Func<T> action, int timeout, CancellationToken? globalCancellation = null)
var result = default(T); //return default for error
var localCancellation = new CancellationTokenSource();
var localAndGlobalCancellation =
CancellationTokenSource.CreateLinkedTokenSource(localCancellation.Token,
globalCancellation.HasValue ?
globalCancellation.Value :
CancellationToken.None);
Task cancelationTask = null;
Task actionTask = null;
try
cancelationTask = Task.Delay(timeout, localAndGlobalCancellation);
actionTask = Task.Factory.StartNew(() =>
result = action.Invoke();
, localAndGlobalCancellation);
catch (Exception ex)
Trace.WriteLine(ex.Message);
localCancellation.Cancel();
return null;
await Task.WhenAny(actionTask, cancelationTask).ContinueWith(t => localCancellation.Cancel());
return result;
Change the work method to return true or false, something like:
public bool CheckForUpdate()
using (var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient())
var sw = new SpinWait();
while (!wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID)) //maybe something shorter would work :) some variables are nice for debugging
sw.SpinOnce(); //magic Thread.Sleep(5) replacement with lots of goodies :) nice class to look at
Thread.Sleep(2000); //for the importer
return true;
And then:
var success = WaitForActionCompletionOrTimeout(() => CheckForUpdate, 600000 ); //I would so like 6.minutes.in.miliseconds.... ah dreams
This sort of approach (cancelling the worker) could also be done with threads in a much shorter and brute-forcier way for a slow performance increase in case of very low timeouts.
I would also advise using using and if WcfMonitoring is not IDisposable, to make it IDisposable.
One more question: What is the intent/difference between calling Abort and Close in your code?
This is a rough draft, since I do not know the overall picture of your project. Some design might be improved to not even use this code (events, semaphores, mutexes, and other more predictable synchronization mechanisms). I rarely use this pattern for code that I control, more for code I cannot that I know is blocking. This approach is risky, as it can lead to undesired state and data loss. You have been warned! (http://thedailywtf.com/articles/My-Tales) for reference!)
If you stay on this path, I recommend A separate class/method be responsible for this sort of behaviour, to favour reuse, this also includes the possibility of having a CancellationToken passed in, just in case you change your mind about the request:
public async Task<T> WaitForActionCompletionOrTimeout<T>(Func<T> action, int timeout, CancellationToken? globalCancellation = null)
var result = default(T); //return default for error
var localCancellation = new CancellationTokenSource();
var localAndGlobalCancellation =
CancellationTokenSource.CreateLinkedTokenSource(localCancellation.Token,
globalCancellation.HasValue ?
globalCancellation.Value :
CancellationToken.None);
Task cancelationTask = null;
Task actionTask = null;
try
cancelationTask = Task.Delay(timeout, localAndGlobalCancellation);
actionTask = Task.Factory.StartNew(() =>
result = action.Invoke();
, localAndGlobalCancellation);
catch (Exception ex)
Trace.WriteLine(ex.Message);
localCancellation.Cancel();
return null;
await Task.WhenAny(actionTask, cancelationTask).ContinueWith(t => localCancellation.Cancel());
return result;
Change the work method to return true or false, something like:
public bool CheckForUpdate()
using (var wcfmonitoring = new WCFMonitoring.MonitoringDatabaseClient())
var sw = new SpinWait();
while (!wcfmonitoring.CheckForEquipmentUpdate(Authentication.GetSessionID(Session), Authentication.GetPTO(Session), ID)) //maybe something shorter would work :) some variables are nice for debugging
sw.SpinOnce(); //magic Thread.Sleep(5) replacement with lots of goodies :) nice class to look at
Thread.Sleep(2000); //for the importer
return true;
And then:
var success = WaitForActionCompletionOrTimeout(() => CheckForUpdate, 600000 ); //I would so like 6.minutes.in.miliseconds.... ah dreams
This sort of approach (cancelling the worker) could also be done with threads in a much shorter and brute-forcier way for a slow performance increase in case of very low timeouts.
I would also advise using using and if WcfMonitoring is not IDisposable, to make it IDisposable.
One more question: What is the intent/difference between calling Abort and Close in your code?
edited Mar 3 at 23:47
answered Mar 3 at 17:42
Alexandru ClonÃÂea
1235
1235
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188674%2flong-running-operation-with-timeout%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
have you considered async/await
â Nkosi
Mar 2 at 12:45
Ok, good idea. I can return async Task<bool> and await Task.Delay(2000) and await Task.Delay(10000).
â Raskolnikov
Mar 2 at 13:16
Yes which would be a lot cleaner than blocking thread
â Nkosi
Mar 2 at 13:19
You could also consider changing the approach and using a timer as apposed to a busy wait....just thinking aloud here
â Nkosi
Mar 2 at 13:44