|
-
Oct 20th, 2022, 09:15 AM
#1
[RESOLVED] Await Question
I have a small program that does some downloads. Some of those take a fair amount of time, but the download itself may not be the issue. The design looks like this:
Code:
Sub Main()
Dim tskLst As New List(Of Task)
LogInfoToDB("General", "All process began.", "", False)
tskLst.Add(ProcA)
tskLst.Add(ProcB)
tskLst.Add(ProcC)
Task.WaitAll(tskLst.ToArray)
LogInfoToDB("General", "All process completed.", "", False)
End Sub
Public Async Function ProcA() As Task(Of Boolean)
LogInfoToDB("ProcA", "process A began.", "", False)
'Do the download and do something with the data.
LogInfoToDB("ProcA", "process A completed.", "", False)
End Function
Public Async Function ProcB() As Task(Of Boolean)
LogInfoToDB("ProcB", "process B began.", "", False)
'Do the download and do something with the data.
LogInfoToDB("ProcB", "process B completed.", "", False)
End Function
Public Async Function ProcC() As Task(Of Boolean)
LogInfoToDB("ProcC", "process C began.", "", False)
'Do the download and do something with the data.
LogInfoToDB("ProcC", "process C completed.", "", False)
End Function
The names have been changed for simplicity. Each Proc does virtually the same thing. It attempts a download where the only difference between the three is a part of the URL.
As it turns out, Proc C is super fast, Proc A is quite slow, and Proc B is intermediate in speed. By quite slow, though, I mean that Proc A is taking a couple seconds, while Proc C is taking a few milliseconds.
The logging included writing the current time to a DB record along with a message, as shown. Because of that logging, I could tell when each process began and ended.
As it turned out, Proc B was failing with a semi-cryptic error about a thread being canceled. I wasn't doing that, but a bit of research suggested that a timeout was a big cause of that exception, and that was possible. Therefore, I decided to just cause Proc B to delay a little while before starting, so that it would happen only after the other two had finished. To do this, I made this change:
Code:
Public Async Function ProcB() As Task(Of Boolean)
Await Task.Delay(60000)
LogInfoToDB("ProcB", "process B began.", "", False)
'Do the download and do something with the data.
LogInfoToDB("ProcB", "process B completed.", "", False)
End Function
What I thought that would do would be to pause ProcB for 10 minutes. Based on the logging, what it actually did was quite a bit different from that. For one thing, the log record "process B began." was written to the database exactly as it always had been. In other words, that line didn't delay the start in any way. I thought that's what it was supposed to do based on some example I had read. Perhaps I misunderstood. Can somebody explain to me what Await Task.Delay() actually does in this example? It certainly doesn't pause the current thread in any noticeable way.
The second thing it might have done is harder to explain. The download neither appeared to succeed nor fail. No further messages were logged from that thread, and the function ProcB never returned, so the WaitAll in Sub Main...may still be waiting, for all I know.
I believe this was working when I used Thread.Sleep rather than Await Task.Delay(), I just thought that the latter was the more appropriate thing to do. Apparently, I was wrong about that. What does it do?
My usual boring signature: Nothing
 
-
Oct 20th, 2022, 09:19 AM
#2
Re: Await Question
One thing I can add is that I set up a simple test, and Await Task.Delay(10000) did exactly what I thought it would do. A breakpoint right after that line was not reached until 10 seconds had elapsed. So why is it not doing so in my working program?
My usual boring signature: Nothing
 
-
Oct 20th, 2022, 09:28 AM
#3
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Oct 20th, 2022, 09:51 AM
#4
Re: Await Question
I had read that, but until you posted that reply, I hadn't recognized the significance of it. I am now running a further test to see how it applies to my situation.
However, I have to run off to a meeting, so the test will await my return.
In the meantime, I also realized what was going on in the second part of my question. I know why the download never finished. It is only tangentially related to the main question. If I can understand what I did wrong with that delay a bit better, then I can solve the other part easily.
My usual boring signature: Nothing
 
-
Oct 20th, 2022, 09:57 AM
#5
Re: Await Question
I'm not sure how long running async processes will respond to times delay or if the actually problem is what Zvoni link suggest but I would first be using task.WhenAll before starting to block async threads.
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Oct 20th, 2022, 10:36 AM
#6
Please remember next time...elections matter!
-
Oct 20th, 2022, 10:56 AM
#7
Re: Await Question
To my eyes that seems a bit cumbersome.
Not only you have to run the actual sproc that Shaggy said it takes too long but you add extra time before running it, let alone any deadlock issues that might arise.
Tho I haven't used it so I can't be sure about it's behavior.
At worst I would just be running the sprocs one by one to see if B will actually finish and then planing the async again.
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Oct 20th, 2022, 10:57 AM
#8
Re: Await Question
 Originally Posted by Shaggy Hiker
Code:
Await Task.Delay(60000)
What I thought that would do would be to pause ProcB for 10 minutes.
Probably irrelevant, or just a typo by you, but 60000ms = 60s = 1 minute.
-
Oct 20th, 2022, 11:02 AM
#9
Re: Await Question
To get this to work I made some changes.
Code:
Public Sub FooBar()
Dim tskLst As New List(Of Task(Of Boolean))()
Debug.WriteLine("General - All process began.")
tskLst.Add(Task.Run(Function()
Return ProcA()
End Function))
tskLst.Add(Task.Run(Function()
Return ProcB()
End Function))
tskLst.Add(Task.Run(Function()
Return ProcC()
End Function))
Task.WaitAll(tskLst.ToArray)
Dim ctTrue As Integer = (From t In tskLst Where t.Result Select t).Count
Debug.WriteLine("General - All process completed.")
End Sub
Public Async Function ProcA() As Task(Of Boolean)
Debug.WriteLine("process A began.")
'Do the download and do something with the data.
Debug.WriteLine("process A completed.")
Return True
End Function
Public Async Function ProcB() As Task(Of Boolean)
Await Task.Delay(5000)
Debug.WriteLine("process B began.")
'Do the download and do something with the data.
Debug.WriteLine("process B completed.")
Return True
End Function
Public Async Function ProcC() As Task(Of Boolean)
Debug.WriteLine("process C began.")
'Do the download and do something with the data.
Debug.WriteLine("process C completed.")
Return False
End Function
Before those changes I never made it past the Await Task.Delay in ProcB.
Hope this helps.
-
Oct 20th, 2022, 01:54 PM
#10
Re: Await Question
 Originally Posted by OptionBase1
Probably irrelevant, or just a typo by you, but 60000ms = 60s = 1 minute.
Actually, that wasn't totally a typo, or at least I no longer remember. At first, I did mean to pause for 10 minutes, but then realized that the other two processes finished in less than one minute, so waiting that long served no purpose. Somewhere along that timeline, I wrote that line. So, did I mean 10 minutes and left off a zero, or did I mean 1 minute? I don't remember. Either one should work.
My usual boring signature: Nothing
 
-
Oct 20th, 2022, 01:55 PM
#11
Re: Await Question
 Originally Posted by dbasnett
To get this to work I made some changes.
Code:
Public Sub FooBar()
Dim tskLst As New List(Of Task(Of Boolean))()
Debug.WriteLine("General - All process began.")
tskLst.Add(Task.Run(Function()
Return ProcA()
End Function))
tskLst.Add(Task.Run(Function()
Return ProcB()
End Function))
tskLst.Add(Task.Run(Function()
Return ProcC()
End Function))
Task.WaitAll(tskLst.ToArray)
Dim ctTrue As Integer = (From t In tskLst Where t.Result Select t).Count
Debug.WriteLine("General - All process completed.")
End Sub
Public Async Function ProcA() As Task(Of Boolean)
Debug.WriteLine("process A began.")
'Do the download and do something with the data.
Debug.WriteLine("process A completed.")
Return True
End Function
Public Async Function ProcB() As Task(Of Boolean)
Await Task.Delay(5000)
Debug.WriteLine("process B began.")
'Do the download and do something with the data.
Debug.WriteLine("process B completed.")
Return True
End Function
Public Async Function ProcC() As Task(Of Boolean)
Debug.WriteLine("process C began.")
'Do the download and do something with the data.
Debug.WriteLine("process C completed.")
Return False
End Function
Before those changes I never made it past the Await Task.Delay in ProcB.
Hope this helps.
Yeah, it helps. That's what I was headed towards when I got called away by the meeting.
My usual boring signature: Nothing
 
-
Oct 20th, 2022, 01:56 PM
#12
Re: Await Question
 Originally Posted by Shaggy Hiker
Actually, that wasn't totally a typo, or at least I no longer remember. At first, I did mean to pause for 10 minutes, but then realized that the other two processes finished in less than one minute, so waiting that long served no purpose. Somewhere along that timeline, I wrote that line. So, did I mean 10 minutes and left off a zero, or did I mean 1 minute? I don't remember. Either one should work.
My initial thought was, Shaggy must be a super patient person to introduce an intentional 10 minute pause to something to see if it then would work. If I'm troubleshooting something, I get antsy if I have to wait an extra 10 seconds.
-
Oct 20th, 2022, 02:27 PM
#13
Re: Await Question
After a bit of testing, it looks like I have a solution, but I'd have to say that I still don't quite understand why it has to be this way. What DB wrote works, I just don't understand why the Task.Run part is necessary. That link talks about it a bit, and links to other things, so I guess I have more to read, but if anybody wants to explain it more thoroughly, feel free.
My usual boring signature: Nothing
 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|