Long running operation with timeout

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite
1












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;







share|improve this question





















  • 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
















up vote
2
down vote

favorite
1












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;







share|improve this question





















  • 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












up vote
2
down vote

favorite
1









up vote
2
down vote

favorite
1






1





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;







share|improve this question













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;









share|improve this question












share|improve this question




share|improve this question








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
















  • 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










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?






share|improve this answer























    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    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






























    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?






    share|improve this answer



























      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?






      share|improve this answer

























        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?






        share|improve this answer















        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?







        share|improve this answer















        share|improve this answer



        share|improve this answer








        edited Mar 3 at 23:47


























        answered Mar 3 at 17:42









        Alexandru Clonțea

        1235




        1235






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            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













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation