Closed brotherhorse closed 2 months ago
Code:
var item2 = await _fusionCache.GetOrSetAsync<TItem>(realKey, OnCallBack);
async Task OnCallBack<TItem>(FusionCacheFactoryExecutionContext <TItem> context,CancellationToken token)
{
var item = await readObjectAsync();
if(item is null)
{
if(context.Options.Duration.Seconds>60)
context.Options.Duration=TimeSpan.FromMinutes(1);
}
return item!;
}
Why are generic types removed from the code after I submit the edited question
Why are generic types removed from the code after I submit the edited question
When you post some code, you need to enclose it in triple-backtick (the character ` ), like this:
var foo = "bar";
Otherwise the < character is interpreted as html, and will be processed.
Also, it is suggested to specify the language, like "```csharp"
Lokk here for more info.
PS: I updated your original comment to fix the code rendering issues, hope this helps.
Hi @brotherhorse
TItem is a class or record,OnCallBack must return a UNnullable TItem
Ok, so this is a constraint.
but readObjectAsync return a nullable TItem, so I return item!. But I don't think this meets strict standards
In general I agree: if a method MUST NOT return null
and it calls another method that CAN return null
, you need to handle that case specifically: one way may be to use a default value of type TItem (non null
of course), and return it instead of null
.
Solution
factory return nullable TValue
I don't understand 2 things:
Help me understand more what is the problem related to FusionCache.
I don't know if this is what you are looking for, but you can use TItem?
(nullable TItem) in the GetOrSet
call, like this:
var item2 = await _fusionCache.GetOrSetAsync<TItem?>(realKey, OnCallBack);
async Task<TItem?> OnCallBack(FusionCacheFactoryExecutionContext<TItem?> context, CancellationToken token)
{
var item = await readObjectAsync();
if (item is null)
{
if (context.Options.Duration.Seconds > 60)
context.Options.Duration = TimeSpan.FromMinutes(1);
}
return item;
}
Is this what you meant?
The other way, as I said above, is to use a (non null
) default value of type TItem:
TItem myDefaultValue = ... ;
var item2 = await _fusionCache.GetOrSetAsync<TItem>(realKey, OnCallBack);
async Task<TItem> OnCallBack(FusionCacheFactoryExecutionContext<TItem> context, CancellationToken token)
{
var item = await readObjectAsync();
if (item is null)
{
if (context.Options.Duration.Seconds > 60)
context.Options.Duration = TimeSpan.FromMinutes(1);
}
return item ?? myDefaultValue;
}
Oh, also: there's a bug in your code that checks for the current cache duration, specifically here:
if (context.Options.Duration.Seconds > 60)
context.Options.Duration = TimeSpan.FromMinutes(1);
In the code above Duration.Seconds
gives you the "seconds component of the time interval" (see here).
This is NOT the same as getting the whole TimeSpan
itself expressed in seconds, for which you have to use TimeSpan.TotalSeconds
(see here).
For example if you have a TimeSpan
with a value of 10 min and 20 sec
:
TimeSpan.Seconds
you'll get 20
TimeSpan.TotalSeconds
you'll get 620
Hope this helps!
- TotalSeconds
Yes,it is a mistake,it should be TotalSeconds
What I mean is this:
await _fusionCache.GetOrSetAsync<TItem?>(realKey, OnCallBack)
async Task<TItem?> OnCallBack(FusionCacheFactoryExecutionContext<TItem?> context, CancellationToken token)
Thank you!
Problem
TItem is a class or record,OnCallBack must return a UNnullable TItem,but readObjectAsync return a nullable TItem, so I return item!. But I don't think this meets strict standards
Code:
Solution
factory return nullable TValue
==>