2

I have this code doing what I want:

        TriggerSomeExternalProcess();
        double secondsElapsed = 0;
        DateTime startTime = DateTime.UtcNow;
        double timeoutInSeconds = 10;
        while (secondsElapsed < timeoutInSeconds) {
            // TODO: this seems bad...
            secondsElapsed = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
        }
        CheckStatusOfExternalProcess();

The goal is to TriggerSomeExternalProcess and then CheckStatusOfSomeExternalProcess - but that process runs on the same thread so I can't do Thread.Sleep(). It's an ongoing process that can't be awaited.

I feel like the above while loop is wrong - what pattern do you employ when you need to wait without blocking your thread?

copy-pasted from a comment on one of the answers unfortunately I can't touch the code in the ExternalProcess. I'm writing a test and those are the methods I have access to. I know it's less than ideal

klashar
  • 2,519
  • 2
  • 28
  • 38
SB2055
  • 12,272
  • 32
  • 97
  • 202
  • Possible duplicate of [Asynchronously wait for Task to complete with timeout](http://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout) – Connell.O'Donnell Feb 16 '17 at 17:40
  • Is using a Timer an option? – Peter Bons Feb 16 '17 at 17:43
  • @PeterBons I think so.... I'll do some research now on how to use that in this case. – SB2055 Feb 16 '17 at 17:44
  • This is hard to answer w/o knowing the true nature of your external `status`, do you just want to wait it out till it finishes, is it a web call etc. I'd say you're thinking the wrong way about it, in most cases `it can be awaited` you just need to reshuffle your code a bit, I personally don't see any need for it to be split like that, but depends. It also depends on the rest of the code, i.e. the caller context. While loop is definitely not the way to go as you have much better options. – NSGaga-mostly-inactive Feb 16 '17 at 17:49
  • What prevents you from awaiting it if you wrap it in a `Task.Run`? – Jcl Feb 16 '17 at 17:49
  • `ut that process runs on the same thread so I can't do Thread.Sleep(). It's an ongoing process that can't be awaited.` - this doesn't make sense. If you can use a busy loop to wait some time, then you can use `Thread.Sleep`. – Stephen Cleary Feb 16 '17 at 18:03
  • @StephenCleary if I use `Thread.Sleep` then the external process (which runs on a timer tick every n ms) will not execute. – SB2055 Feb 16 '17 at 18:08
  • 1
    @SB2055 if you use that `while` busy loop, it won't either (unless it's on another thread) – Jcl Feb 16 '17 at 18:12

2 Answers2

2

Instead of using a CheckStatusOfExternalProcess() Method u may be able to add an StatusChangedEvent onto the ExternalProcess thing and attach a EventHandler onto it. That way your eventhandler gets called, when the status has changed.

Is that a possibility for you?

Btw: If both of your processes run on the same Thread - how can that be not blocking?

Tobias Theel
  • 3,088
  • 2
  • 25
  • 45
0

I assume the process that's external is not your own. Therefore it can't take a callback action. It can't give a heartbeat (send periodically back it's current status). And it can't subscribe to it's status changing. These would be the normal ways to deal with it.

In which case you could just use something like this

Task.delay(TimeSpan.FromSeconds(10))).ContinueWith(() => CheckStatusOfExternalProcess())

continue with will fire as soon the first task is complete but now you can continue on in your code without worrying about it

Noah Reinagel
  • 402
  • 3
  • 6
  • :) as always tell me what made you down-vote so I can avoid it in the future. – Noah Reinagel Feb 16 '17 at 18:04
  • Why do you need a `StartNew` here? You can simply `await Task.Delay().ContinueWith(…)` instead, you're adding too much iverhead. – VMAtm Feb 18 '17 at 03:37