WmsAsyncCodeActivity
WMS 2020 (1.0.3)
Die WmsAsyncCodeActivity ist eine Ableitung der herkömmlichen AsyncCodeActivity (System.Activities.AsyncCodeActivity).
Unterschiede zur System.Activities.AsyncCodeActivity
Statt der BeginExecute-Methode implementieren Sie die BeginExectuteIntern-Methode
Statt der EndExecute-Methode implementieren Sie die OnTaskExecuted-Methode
Zusätzliches Property "Disabled"
Implementiert IDisposable
WmsAsyncCodeActivity (C#)
using System;
using System.Activities;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using Accantum.Wms.ActivityContracts.Attributes;
using Accantum.Wms.ActivityContracts.Properties;
namespace Accantum.Wms.ActivityContracts.Base
{
/// <summary>
/// Basisklasse für asynchrone Aktivitäten
/// </summary>
/// <typeparam name="T">Typ den der Task zurückliefert</typeparam>
public abstract class WmsAsyncCodeActivity<T> : AsyncCodeActivity, IWmsActivityBase
{
/// <summary>
/// Kennzeichen, ob die Aktivität auskommentiert ist. Wenn Ja, wird die ExecuteMethode nicht aufgerufen.
/// </summary>
[ExcludeInAnnotation]
[LocalizedDisplayName("Activity_Disabled", typeof(WmsActivityResources))]
[LocalizedDescription("Activity_DisabledDesc", typeof(WmsActivityResources))]
public bool Disabled { get; set; }
/// <summary>
/// prüft die Aktivitätsversion (<see cref="SupersedesAttribute"/>) und das Disabled-Property
/// </summary>
protected override void CacheMetadata(CodeActivityMetadata a_oMetadata)
{
//Bei deaktivierten Aktivitäten Fehler nicht anzeigen
if (Disabled)
{
a_oMetadata.SetValidationErrorsCollection(null);
a_oMetadata.AddValidationError(CreateDisabledValidationWarning());
}
else {
base.CacheMetadata(a_oMetadata);
}
SupersedesAttribute.AddWarningIfIsSuperseded(GetType(), a_oMetadata);
}
/// <summary>
/// Methode wird vor der Ausführung aufgerufen und prüft das Disabled-Kennzeichen.
/// </summary>
/// <returns>true, wenn die Aktivität ausgeführt werden soll.</returns>
protected virtual bool BeforeExecute(AsyncCodeActivityContext context)
{
if (!Disabled)
return true;
var wmsApi = context.GetExtension<IWmsApiExtension>();
wmsApi.TrackInfo(context, GetDisabledWarning());
return false;
}
protected sealed override IAsyncResult BeginExecute(AsyncCodeActivityContext a_oContext, AsyncCallback a_oCallback, object a_oState)
{
if (!BeforeExecute(a_oContext))
return Task.FromResult(default(T));
try
{
return BeginExecuteIntern(a_oContext, a_oCallback, a_oState);
}
catch (Exception ex)
{
DisposeObjects(a_oContext.UserState);
return FromTask(Task.FromException<T>(ex), a_oCallback, a_oState);
}
}
protected abstract IAsyncResult BeginExecuteIntern(AsyncCodeActivityContext a_oContext, AsyncCallback a_oCallback, object a_oState);
/// <summary>
/// Erzeugt aus einem Task ein IAsyncResult und beinhaltet Fehlerbehandlung
/// </summary>
protected IAsyncResult FromTask(Task<T> a_oTask, AsyncCallback a_oCallback, object a_oState)
{
...
}
protected sealed override void EndExecute(AsyncCodeActivityContext a_oContext, IAsyncResult a_oResult)
{
var oTask = a_oResult as Task<T>;
try
{
OnTaskExecuted(a_oContext, oTask != null ? oTask.Result : default, a_oResult);
}
catch (AggregateException ex)
{
...
}
finally
{
DisposeObjects(a_oContext.UserState);
}
}
protected override void Cancel(AsyncCodeActivityContext a_oContext)
{
// Implement any cleanup as a result of the asynchronous work
// being canceled, and then call MarkCanceled.
if (a_oContext.IsCancellationRequested)
a_oContext.MarkCanceled();
DisposeObjects(a_oContext.UserState);
}
protected abstract void OnTaskExecuted(AsyncCodeActivityContext a_oContext, T a_oTaskResult, IAsyncResult a_oResult);
protected virtual void DisposeObjects(object a_oUserState)
{
(a_oUserState as IDisposable)?.Dispose();
}
}
}