Long Polling در WCF
نویسنده: مسعود پاکدل
تاریخ: ۱۳۹۲/۱۱/۱۷ ۱۴:۱۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public abstract class LongPollingAsyncResult<TResult> : IAsyncResult where TResult : class
{
#region - Fields -
private AsyncCallback _callback;
private TimeSpan _timoutSpan;
private TimeSpan _intervalWaitSpan;
#endregion
#region - Properties -
public Exception Exception { get; private set; }
public TResult Result { get; private set; }
public object SyncRoot { get; private set; }
#endregion
#region - Ctor -
public LongPollingAsyncResult(AsyncCallback callback, object asyncState, int timeoutSeconds = 300, int intervalWaitMilliseconds = 500)
{
SyncRoot = new object();
_callback = callback;
AsyncState = asyncState;
AsyncWaitHandle = new ManualResetEvent(IsCompleted);
_timoutSpan = TimeSpan.FromSeconds(timeoutSeconds);
_intervalWaitSpan = TimeSpan.FromMilliseconds(intervalWaitMilliseconds);
ThreadPool.QueueUserWorkItem(new WaitCallback(LoopWithIntervalAndTimeout));
}
#endregion
#region - Private Helper Methods -
private void LoopWithIntervalAndTimeout(object input)
{
try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (!IsCompleted)
{
if (stopwatch.Elapsed > _timoutSpan)
throw new TimeoutException();
DoWork();
if (!IsCompleted)
Thread.Sleep(_intervalWaitSpan);
}
}
catch (Exception e)
{
Complete(null, e);
}
}
#endregion
#region - Protected/Abstract Methods -
protected void Complete(TResult result, Exception e = null, bool completedSynchronously = false)
{
lock (SyncRoot)
{
CompletedSynchronously = completedSynchronously;
Result = result;
Exception = e;
IsCompleted = true;
if (_callback != null)
_callback(this);
}
}
protected abstract void DoWork();
#endregion
#region - Public Methods -
public TResult WaitForResult()
{
if (!IsCompleted)
AsyncWaitHandle.WaitOne();
if (Exception != null)
{
if (Exception is TimeoutException && WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.RequestTimeout;
throw Exception;
}
return Result;
}
#endregion
#region - IAsyncResult Implementation -
public object AsyncState { get; private set; }
public WaitHandle AsyncWaitHandle { get; private set; }
public bool CompletedSynchronously { get; private set; }
public bool IsCompleted { get; private set; }
#endregion
} [OperationContract] public string GetNotification();
[OperationContract(AsyncPattern = true)] public IAsyncResult BeginWaitNotification(AsyncCallback callback, object state); public string EndWaitNotification(IAsyncResult result);
public class MyNotificationResult : LongPollingAsyncResult<string>
{
protected override DoWork()
{
کدهای مورد نظر را اینجا قرار دهید
base.Complete(...)
}
} public IAsyncResult BeginWaitNotification(AsyncCallback callback, object state)
{
return new MyNotificationResult(callback, state);
}
public string EndWaitNotification(IAsyncResult result)
{
MyNotificationResult myResult = result as MyNotificationResult;
if(myResult == null)
throw new ArgumentException("result was of the wrong type!");
myResult.WaitForResult();
return myResult.Result;
}