انجام پی در پی اعمال Async به کمک Iterators - قسمت دوم
نویسنده: وحید نصیری
تاریخ: ۱۳۸۹/۰۴/۱۱ ۰۰:۰۱:۰۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
using System;
namespace SLAsyncTest.Helper
{
public interface IResult
{
void Execute();
event EventHandler Completed;
}
}
using System;
using System.Collections.Generic;
namespace SLAsyncTest.Helper
{
public class ResultEnumerator
{
private readonly IEnumerator<IResult> _enumerator;
public ResultEnumerator(IEnumerable<IResult> children)
{
_enumerator = children.GetEnumerator();
}
public void Enumerate()
{
childCompleted(null, EventArgs.Empty);
}
private void childCompleted(object sender, EventArgs args)
{
var previous = sender as IResult;
if (previous != null)
previous.Completed -= childCompleted;
if (!_enumerator.MoveNext())
return;
var next = _enumerator.Current;
next.Completed += childCompleted;
next.Execute();
}
}
}
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Threading;
namespace SLAsyncTest.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode
= AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService
{
[OperationContract]
public int GetNumber(int number)
{
Thread.Sleep(2000);//Simulating a log running operation
return number * 2;
}
}
}
using System;
using SLAsyncTest.Helper;
namespace SLAsyncTest.Model
{
public class GetNumber : IResult
{
public int Result { set; get; }
public bool HasError { set; get; }
private int _num;
public GetNumber(int num)
{
_num = num;
}
#region IResult Members
public void Execute()
{
var srv = new TestServiceReference.TestServiceClient();
srv.GetNumberCompleted += (sender, e) =>
{
if (e.Error == null)
Result = e.Result;
else
HasError = true;
Completed(this, EventArgs.Empty); //run the next IResult
};
srv.GetNumberAsync(_num);
}
public event EventHandler Completed;
#endregion
}
}
private void doFetch(object obj)
{
new ResultEnumerator(executeAsyncOps()).Enumerate();
}
private IEnumerable<IResult> executeAsyncOps()
{
FinalResult = 0;
IsBusy = true; //Show BusyIndicator
//Sequential Async Operations
var asyncOp1 = new GetNumber(10);
yield return asyncOp1;
//using the result of the previous step
if(asyncOp1.HasError)
{
IsBusy = false; //Hide BusyIndicator
yield break;
}
var asyncOp2 = new GetNumber(asyncOp1.Result);
yield return asyncOp2;
FinalResult = asyncOp2.Result; //Bind it to the UI
IsBusy = false; //Hide BusyIndicator
}