Return the same value for multiple function calls during query execution using async / wait

Given the following function:

public async Task<int> GetValue() { var value = await GetValueFromServer(); return value; } 

I would like to do it. The GetValue () function can be called from different parts of the program. While GetValueFromServer () is running, I do not want to initiate another call. All calls to GetValue (), while GetValueFromServer () is working, must return the same value and not initiate another call. The call to GetValue (), while GetValueFromServer () does not work, should initiate a new call to GetValueFromServer ().

Example:

 0.0: var a = await GetValue() 0.1: call to GetValueFromServer() 0.3: var b = await GetValue(); 0.6: var c = await GetValue(); 0.7: GetValueFromServer() returns 1 0.9: var d = await GetValue(); 1.0: call to GetValueFromServer() 1.3 GetValueFromServer() returns 2 

Calls to GetValue () on 0.0, 0.3, and 0.6 should only call one call to GetValueFromServer (). All three subscribers should receive the same value. A call to GetValue () at point 0.9 should cause another call to GetValueFromServer ().

I am still stuck in thinking Objective-C, where I would use blocks for this. I would queue blocks and when a server request returns a call to each block that has been queued.

 - (void)getValue:(void(^)(int value))block { [_runningBlocks addObject:[block copy]]; if (_runningBlocks.count > 1) { return; } [self getValueFromServer:^(int value) { for (void(^)(int)b in _runningBlocks) { b(value); } [_runningBlocks removeAllObjects]; ]; } 

Now I would like to accomplish the same thing, but using the async / await pattern. This is intended for use in the Windows Phone 8.1 (RT) application, and if possible, I would like to avoid a third-party library / framework.

+8
c # asynchronous
source share
1 answer

You need to split the same task to return the same value (you need to split this state). To do this, you need to synchronize access.

The following should be more than enough.

 private object padLock = new object(); private Task<int> executingTask; public async Task<int> GetValue() { lock(padLock) { if (executingTask == null || executingTask.IsCompleted) executingTask= GetValueFromServer(); } var value = await executingTask; return value; } 
+8
source share

All Articles