Será mejor que implemente Event Based Asynchronous Pattern para su desarrollo para detectar eventos en todas las etapas.
Básicamente, cómo sería crear primero una interfaz IAsyncCommand de la siguiente manera.
public interface IAsyncCommand<TRequest, TResponse, TCorrelation> : ICommand<TRequest, TResponse>
{
event CommandProgressChangedEventHandler<string, TCorrelation> ProgressChanged;
event CommandCompletedEventHandler<TResponse, TCorrelation> Completed;
bool CancellationPending { get; }
bool IsBusy { get; }
TCorrelation CorrelationId(TRequest request);
void ExecuteAsync(TRequest request);
void ExecuteAsync(TRequest request, CommandCompletedEventHandler<TResponse, TCorrelation> completedCallback, CommandProgressChangedEventHandler<string, TCorrelation> progressCallback);
void CancelAsync();
}
poner en práctica esos dos CommandProgressChangedEventHander y la CommandCompletedEventHandler basado en su escenario y poblar el argumento en consecuencia.
Si asumimos que nuestro hilo debe comprobar si una determinada URL en cuestión es una URL válida, el código es el siguiente ....
public class UrlCheckCommand : AsyncCommandBase<string, bool, string>, IUrlCheckCommand
{
public override string CorrelationId(string request)
{
return request; //Guid.NewGuid().ToString();
}
public override bool Execute(string request)
{
return CommandHelper.CheckUrlValidity(request);
}
}
La clase AsyncCommandBase es una clase abstracta que implementa la interfaz IAsyncCommand . El esqueleto de esta clase se define a continuación.
public abstract class AsyncCommandBase<TRequest, TResponse, TCorrelation> : IAsyncCommand<TRequest, TResponse, TCorrelation>
{
protected AsyncOperation operation = null;
protected BackgroundWorker worker = null;
#region IAsyncCommand<TRequest,TResponse,TCorrelation> Members
//Implement all the interface members as per your use....
#endregion
protected void worker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = Execute((TRequest)e.Argument);
}
protected void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
OnProgressChanged(e);
}
protected void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
OnCompleted(e);
}
protected void ReportProgress(int percentageProgress, string message)
{
if (worker != null && worker.WorkerReportsProgress)
worker.ReportProgress(percentageProgress, message);
else
OnProgressChanged(new ProgressChangedEventArgs(percentageProgress, message));
}
protected void OnProgressChanged(ProgressChangedEventArgs e)
{
if (ProgressChanged != null)
{
SendOrPostCallback callback = new SendOrPostCallback(delegate { ProgressChanged(this, new CommandProgressChangedEventArgs<string, TCorrelation>(e.ProgressPercentage, e.UserState as string, (TCorrelation)operation.UserSuppliedState)); });
operation.Post(callback, null);
}
}
protected void OnCompleted(RunWorkerCompletedEventArgs e)
{
if (Completed != null)
{
TResponse response = default(TResponse);
if (e.Error == null)
response = (TResponse)e.Result;
SendOrPostCallback callback = new SendOrPostCallback(delegate { Completed(this, new CommandCompletedEventArgs<TResponse, TCorrelation>(response, e.Error, (TCorrelation)operation.UserSuppliedState, e.Cancelled)); });
operation.PostOperationCompleted(callback, null);
}
}
}
Puede completar el controlador de progreso y evento finalizado y la clave es la población de argumento. Incluso puede usarlo para completar el progreso porcentual, estado de usuario, etc. ...
¿alguna solución final con código fuente completo? – Kiquenet