Let's say this getPhotoAsync
method can be invoked a few times a second, and that the responses from the remote server can take anywhere from half a second to thirty seconds, depending on the size of the payload. So there will be several concurrent requests pending. Does .NET keep track "behind the scenes" of which response goes with which request? Is there any chance that info
could be associated with the wrong response from the remote server?
public async Task<PhotoWithInfo> getPhotoAsync(object info, string photoid)
{
//<snip> build url with photoid
var request = WebRequest.Create(new System.Uri(url));
var response = await request.GetResponseAsync();
byte[] photo=null;
// <snip> read the response stream and return a byte array
photo = myMemoryStream.ToArray();
var foo = new PhotoWithInfo();
foo.bytes = photo;
foo.Info = info;
return foo;
}
1 Answer 1
Is there any chance that info could be associated with the wrong response from the remote server?
No.
When your await
method is executed, the framework signs your Task onto the current thread as a continuation, and returns control of execution flow back to you. So now you're holding a reference to that task. When the async method returns, the framework will populate your Task with the correct value, or it will block when you interrogate the Task for its value if the async method hasn't returned yet.
Either way, you're holding the correct Task, so you'll get the correct value back. WebRequest
is an atomic class; it doesn't share state with other instances of WebRequest
, and your usage of WebRequest
here is local to the class and the Task. Further, your WebResponse
is tied to this specific WebRequest
instance. So no, there is no possibility of race conditions, because there is no shared state.
-
I read the question as asking if
GetResponseAsync
always returns a value related to the request that calls it, not ifawait
runs the continuation for theTask
being awaited.Servy– Servy2016年08月01日 20:54:27 +00:00Commented Aug 1, 2016 at 20:54 -
Alright, but that doesn't have anything to do with
async
await
. Therequest
object is local to this method, so it seems unlikely that other requests are commingled.Robert Harvey– Robert Harvey2016年08月01日 20:55:11 +00:00Commented Aug 1, 2016 at 20:55 -
Correct; I read it as a red herring. That was my reading of the question, granted, it's not completely clear what he's worried about. I essentially read him as asking if
GetResponseAsync
has bugs, rather than ifawait
has bugs, not that either seems particularly interesting as a question.Servy– Servy2016年08月01日 20:57:05 +00:00Commented Aug 1, 2016 at 20:57 -
The continuation will always pick back up where it left off, but if the method is being called many times in rapid succession, there is no guarantee that the first Task to fire will be the first Task to complete.RubberDuck– RubberDuck2016年08月02日 00:59:56 +00:00Commented Aug 2, 2016 at 0:59
-
@RubberDuck: How is that relevant here? You can use
ContinueWith()
if you need them to execute in a certain sequence, but the Web Requests are still independent from each other.Robert Harvey– Robert Harvey2016年08月02日 01:19:41 +00:00Commented Aug 2, 2016 at 1:19