Stacking await keywords
up vote
-1
down vote
favorite
I am trying to reduce the boiler plate code from getting data from my cache repository. I was basically copying and pasting the same code over and over, so I put all of that logic into a new class, CacheReadCommand. I am trying to do this using async/await as my database repository has already implemented async/await. What has ended up happening is that I got this stack of await keywords when I am trying to execute CacheReadCommand.Read. This is not actually returning anything and leaving the application hung up. Where did I go wrong here?
CacheReadCommand
public class CacheReadCommand : ICacheReadCommand {
private readonly ICacheRepository _repo;
public CacheReadCommand(ICacheRepository repo) {
_repo = repo;
}
public async Task<T> Read<T>(string cacheKey, Func<T> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = query.Invoke();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
}
** Settings Repository **
public async Task<Setting> GetSetting(Guid guid, string key) {
string cacheKey = $"GetSetting_{guid}_{key}";
return await await _readCommand.Read(cacheKey, async () => await ReadOne<Setting>("GetSetting", guid));
}
protected async Task<T> ReadOne<T>(string sql, Guid siteGuid) {
DynamicParameters parms = new DynamicParameters();
parms.Add(PARMNAME_GUID, siteGuid.ToFormattedString());
return await ReadOne<T>(GetCommandDefinition(sql, parms));
}
c# async-await delegates
|
show 2 more comments
up vote
-1
down vote
favorite
I am trying to reduce the boiler plate code from getting data from my cache repository. I was basically copying and pasting the same code over and over, so I put all of that logic into a new class, CacheReadCommand. I am trying to do this using async/await as my database repository has already implemented async/await. What has ended up happening is that I got this stack of await keywords when I am trying to execute CacheReadCommand.Read. This is not actually returning anything and leaving the application hung up. Where did I go wrong here?
CacheReadCommand
public class CacheReadCommand : ICacheReadCommand {
private readonly ICacheRepository _repo;
public CacheReadCommand(ICacheRepository repo) {
_repo = repo;
}
public async Task<T> Read<T>(string cacheKey, Func<T> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = query.Invoke();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
}
** Settings Repository **
public async Task<Setting> GetSetting(Guid guid, string key) {
string cacheKey = $"GetSetting_{guid}_{key}";
return await await _readCommand.Read(cacheKey, async () => await ReadOne<Setting>("GetSetting", guid));
}
protected async Task<T> ReadOne<T>(string sql, Guid siteGuid) {
DynamicParameters parms = new DynamicParameters();
parms.Add(PARMNAME_GUID, siteGuid.ToFormattedString());
return await ReadOne<T>(GetCommandDefinition(sql, parms));
}
c# async-await delegates
1
Theawait awaitdoesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?
– Enigmativity
Nov 19 at 22:09
1
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is aTask<Task<T>>(or Task<Task>), which is the case here.
– Servy
Nov 19 at 22:44
If you want to give an async query to yourReadfunction, you need to ask explicitly for aFunc<Task<T>>and await it. Right now you're callingInvoke()on the delegate, which returns aTask<Setting>and you give it as-is to your repository. I'm fairly certain that this is not what you want
– Kevin Gosse
Nov 19 at 23:13
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46
|
show 2 more comments
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
I am trying to reduce the boiler plate code from getting data from my cache repository. I was basically copying and pasting the same code over and over, so I put all of that logic into a new class, CacheReadCommand. I am trying to do this using async/await as my database repository has already implemented async/await. What has ended up happening is that I got this stack of await keywords when I am trying to execute CacheReadCommand.Read. This is not actually returning anything and leaving the application hung up. Where did I go wrong here?
CacheReadCommand
public class CacheReadCommand : ICacheReadCommand {
private readonly ICacheRepository _repo;
public CacheReadCommand(ICacheRepository repo) {
_repo = repo;
}
public async Task<T> Read<T>(string cacheKey, Func<T> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = query.Invoke();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
}
** Settings Repository **
public async Task<Setting> GetSetting(Guid guid, string key) {
string cacheKey = $"GetSetting_{guid}_{key}";
return await await _readCommand.Read(cacheKey, async () => await ReadOne<Setting>("GetSetting", guid));
}
protected async Task<T> ReadOne<T>(string sql, Guid siteGuid) {
DynamicParameters parms = new DynamicParameters();
parms.Add(PARMNAME_GUID, siteGuid.ToFormattedString());
return await ReadOne<T>(GetCommandDefinition(sql, parms));
}
c# async-await delegates
I am trying to reduce the boiler plate code from getting data from my cache repository. I was basically copying and pasting the same code over and over, so I put all of that logic into a new class, CacheReadCommand. I am trying to do this using async/await as my database repository has already implemented async/await. What has ended up happening is that I got this stack of await keywords when I am trying to execute CacheReadCommand.Read. This is not actually returning anything and leaving the application hung up. Where did I go wrong here?
CacheReadCommand
public class CacheReadCommand : ICacheReadCommand {
private readonly ICacheRepository _repo;
public CacheReadCommand(ICacheRepository repo) {
_repo = repo;
}
public async Task<T> Read<T>(string cacheKey, Func<T> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = query.Invoke();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
}
** Settings Repository **
public async Task<Setting> GetSetting(Guid guid, string key) {
string cacheKey = $"GetSetting_{guid}_{key}";
return await await _readCommand.Read(cacheKey, async () => await ReadOne<Setting>("GetSetting", guid));
}
protected async Task<T> ReadOne<T>(string sql, Guid siteGuid) {
DynamicParameters parms = new DynamicParameters();
parms.Add(PARMNAME_GUID, siteGuid.ToFormattedString());
return await ReadOne<T>(GetCommandDefinition(sql, parms));
}
c# async-await delegates
c# async-await delegates
asked Nov 19 at 21:38
fizch
1,49031936
1,49031936
1
Theawait awaitdoesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?
– Enigmativity
Nov 19 at 22:09
1
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is aTask<Task<T>>(or Task<Task>), which is the case here.
– Servy
Nov 19 at 22:44
If you want to give an async query to yourReadfunction, you need to ask explicitly for aFunc<Task<T>>and await it. Right now you're callingInvoke()on the delegate, which returns aTask<Setting>and you give it as-is to your repository. I'm fairly certain that this is not what you want
– Kevin Gosse
Nov 19 at 23:13
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46
|
show 2 more comments
1
Theawait awaitdoesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?
– Enigmativity
Nov 19 at 22:09
1
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is aTask<Task<T>>(or Task<Task>), which is the case here.
– Servy
Nov 19 at 22:44
If you want to give an async query to yourReadfunction, you need to ask explicitly for aFunc<Task<T>>and await it. Right now you're callingInvoke()on the delegate, which returns aTask<Setting>and you give it as-is to your repository. I'm fairly certain that this is not what you want
– Kevin Gosse
Nov 19 at 23:13
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46
1
1
The
await await doesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?– Enigmativity
Nov 19 at 22:09
The
await await doesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?– Enigmativity
Nov 19 at 22:09
1
1
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is a
Task<Task<T>> (or Task<Task>), which is the case here.– Servy
Nov 19 at 22:44
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is a
Task<Task<T>> (or Task<Task>), which is the case here.– Servy
Nov 19 at 22:44
If you want to give an async query to your
Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting> and you give it as-is to your repository. I'm fairly certain that this is not what you want– Kevin Gosse
Nov 19 at 23:13
If you want to give an async query to your
Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting> and you give it as-is to your repository. I'm fairly certain that this is not what you want– Kevin Gosse
Nov 19 at 23:13
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46
|
show 2 more comments
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
If you want to give an async query to your Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting>.
So instead you should do something like:
public async Task<T> Read<T>(string cacheKey, Func<Task<T>> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = await query();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
If you want to give an async query to your Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting>.
So instead you should do something like:
public async Task<T> Read<T>(string cacheKey, Func<Task<T>> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = await query();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
add a comment |
up vote
0
down vote
accepted
If you want to give an async query to your Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting>.
So instead you should do something like:
public async Task<T> Read<T>(string cacheKey, Func<Task<T>> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = await query();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
If you want to give an async query to your Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting>.
So instead you should do something like:
public async Task<T> Read<T>(string cacheKey, Func<Task<T>> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = await query();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
If you want to give an async query to your Read function, you need to ask explicitly for a Func<Task<T>> and await it. Right now you're calling Invoke() on the delegate, which returns a Task<Setting>.
So instead you should do something like:
public async Task<T> Read<T>(string cacheKey, Func<Task<T>> query) {
T retVal = await _repo.GetValue<T>(cacheKey);
if(retVal == null) {
retVal = await query();
if(retVal != null) {
await _repo.SetValue<T>(cacheKey, retVal);
}
}
return retVal;
}
answered Nov 20 at 7:11
Kevin Gosse
32.4k35271
32.4k35271
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383011%2fstacking-await-keywords%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
The
await awaitdoesn't make sense. This shouldn't compile. Can you please provide a Minimal, Complete, and Verifiable example?– Enigmativity
Nov 19 at 22:09
1
@Enigmativity It makes perfect sense and compiles just fine whenever the expression following it is a
Task<Task<T>>(or Task<Task>), which is the case here.– Servy
Nov 19 at 22:44
If you want to give an async query to your
Readfunction, you need to ask explicitly for aFunc<Task<T>>and await it. Right now you're callingInvoke()on the delegate, which returns aTask<Setting>and you give it as-is to your repository. I'm fairly certain that this is not what you want– Kevin Gosse
Nov 19 at 23:13
@Servy - Yes, but there's no double task here as far as I can see?
– Enigmativity
Nov 20 at 0:38
@KevinGosse implementing Func<Task<T>> did alleviate the second await, however I am still using query.Invoke(). I just have to await that. I have compiled it and tested it. That worked. This solution works for me, if you want to put your comment as an answer, I'll close it.
– fizch
Nov 20 at 0:46