abnormal return #3433
Replies: 3 comments 2 replies
-
For some reason, this code works, but the commented out line still prematurely returns without a value or error when excuted. public class LiquidOperatorQualificationExpirationDateRule : BusinessRule
{
private IPropertyInfo coveredTaskLiquidCdProperty { get; set; }
private IPropertyInfo effectiveDateProperty { get; set; }
private int periodYears;
public LiquidOperatorQualificationExpirationDateRule(IPropertyInfo ExpirationDateProperty, IPropertyInfo CoveredTaskLiquidCdProperty, IPropertyInfo EffectiveDateProperty) : base(ExpirationDateProperty)
{
coveredTaskLiquidCdProperty = CoveredTaskLiquidCdProperty;
effectiveDateProperty = EffectiveDateProperty;
InputProperties = new List<IPropertyInfo> { CoveredTaskLiquidCdProperty, EffectiveDateProperty };
AffectedProperties.Add(ExpirationDateProperty);
}
protected override void Execute(IRuleContext context)
{
if (context.InputPropertyValues[coveredTaskLiquidCdProperty] == null || (short)context.InputPropertyValues[coveredTaskLiquidCdProperty] == 0)
return;
var id = (short)context.InputPropertyValues[coveredTaskLiquidCdProperty];
try
{
//var task = await context.ApplicationContext.GetRequiredService<IDataPortal<CoveredTaskLiquidInfo>>().FetchAsync(id);
GetAsync(context, id).Wait();
DateTime effectiveDate = (DateTime)context.InputPropertyValues[effectiveDateProperty];
DateTime expirationDate = effectiveDate.AddYears(periodYears);
context.AddOutValue(PrimaryProperty, expirationDate);
}
catch (Exception ex)
{
context.AddErrorResult(ex.Message);
}
}
private async Task GetAsync(IRuleContext context, short id)
{
var dpFactory = context.ApplicationContext.GetRequiredService<IDataPortalFactory>();
var task = await dpFactory.GetPortal<CoveredTaskLiquidInfo>().FetchAsync(id);
periodYears = task.RequalificationFrequency;
}
} |
Beta Was this translation helpful? Give feedback.
-
The The compiler does some pretty interesting magic when we use async/await. It actually breaks our code into sections:
When you call the method the "before await" code runs, then the "await" gets invoked, and then the method returns. Yes really! Later, when the "await" completes, the "after await" code is executed. To know when the "after await" code has finished, the calling code needs to await the task returned by |
Beta Was this translation helpful? Give feedback.
-
I don't know if this helps, but here's an example of an async rule that generates an output value: using Csla;
using Csla.Core;
using Csla.Rules;
namespace CslaAsyncRule
{
[Serializable]
public class MyCode : BusinessBase<MyCode>
{
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
public string Name
{
get => GetProperty(NameProperty);
set => SetProperty(NameProperty, value);
}
public static readonly PropertyInfo<int> ValueProperty = RegisterProperty<int>(nameof(Value));
public int Value
{
get => GetProperty(ValueProperty);
set => SetProperty(ValueProperty, value);
}
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new MyAsyncRule(NameProperty, ValueProperty));
}
[Fetch]
private void Fetch()
{ }
}
public class MyAsyncRule : Csla.Rules.BusinessRuleAsync
{
private IPropertyInfo targetProperty;
public MyAsyncRule(IPropertyInfo primaryProperty, IPropertyInfo targetProperty)
{
this.PrimaryProperty = primaryProperty;
InputProperties.Add(primaryProperty);
this.targetProperty = targetProperty;
AffectedProperties.Add(targetProperty);
}
protected override async Task ExecuteAsync(IRuleContext context)
{
var name = context.GetInputValue<string>(PrimaryProperty);
int value;
await Task.Run(() =>
{
value = name.GetHashCode();
context.AddOutValue(targetProperty, value);
});
}
}
} Here's example test code: var portal = provider.GetRequiredService<IDataPortal<MyCode>>();
var obj = await portal.FetchAsync();
obj.Name = "Rocky";
while (obj.IsBusy) { await Task.Delay(1); }
Console.WriteLine($"{obj.Name}, {obj.Name.GetHashCode()} == {obj.Value}");
obj.Name = "Kevin";
while (obj.IsBusy) { await Task.Delay(1); }
Console.WriteLine($"{obj.Name}, {obj.Name.GetHashCode()} == {obj.Value}"); The Here is the output:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I have a business rule that needs to get an object used in the computation. In the execute method of the async business rule, the rule prematurely returns before hitting the if(task == null) statement. I don't understand why. Can someone explain?
Beta Was this translation helpful? Give feedback.
All reactions