This document describes the PX1038 diagnostic.
| Code | Short Description | Type | Code Fix |
|---|---|---|---|
| PX1038 | Async void methods, lambdas, and anonymous methods should not be used with the Acumatica Framework. | Error | Unavailable |
The diagnostic reports all async void methods, lambdas, and anonymous methods.
Use of async void methods and lambdas generally is a bad practice in .Net programming. You cannot await those methods, and exceptions thrown in them are not propagated to the caller. As a result, it is very difficult to handle exceptions properly. The only exception when an async void method can be used is when it is an event handler. The async void method is not awaited, and the caller does not expect a return value. You can find more details about this here.
Acumatica Framework has its own event model and provides its own mechanisms for events subscription that do not support async event handlers. Moreover, Acumatica Framework manages threads. Threads in Acumatica Framework have its own execution model and context. The thread management mechanism of Acumatica Framework does not support the use of async void methods and lambdas.
Due to the reasons listed above, the PX1038 diagnostic forbids all uses of async void methods, lambdas, and anonymous methods. To fix the error shown by the diagnostic, rework the method or the lambda expression to return an awaitable type like Task.
The PX1038 diagnostic does not suggest an automatic code fix.
public class SomeAcumaticaAsyncService
{
public async void CallExternalApiAsync(object data)
{
await _externalApiClient.CallApiAsync(data);
}
public async void CallExternalApiViaLambda(object data)
{
Execute(async () => await _externalApiClient.CallApiAsync(data));
Execute(async delegate { await _externalApiClient.CallApiAsync(data); });
}
private static void Execute(Action action) => action();
}public class SomeAcumaticaAsyncService
{
public async Task CallExternalApiAsync(object data)
{
await _externalApiClient.CallApiAsync(data);
}
public async Task CallExternalApiViaLambda(object data)
{
await Execute(async () => await _externalApiClient.CallApiAsync(data));
}
private static Task Execute(Func<Task> action) => action();
}