|
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Collections.Specialized;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Lifetime;
namespace EventBasedAsync
{
public partial class ServerAsyncWrapper : Component
{
#region MarshalByRefObject Overrides
public override object InitializeLifetimeService()
{
ILease lease = (ILease) base.InitializeLifetimeService();
lease.InitialLeaseTime = TimeSpan.FromDays(1);
lease.RenewOnCallTime = TimeSpan.FromHours(1);
return lease;
}
#endregion
#region Construction
public ServerAsyncWrapper()
{
InitializeComponent();
}
public ServerAsyncWrapper(IContainer container)
{
container.Add(this);
InitializeComponent();
}
#endregion
#region Public Methods
public void DoSomethingAsync(int n, object userState)
{
OperationState opState = new OperationState(n, userState);
lock (userStateToOperationState)
{
userStateToOperationState.Add(userState, opState);
}
DoSomethingDelegate d = new DoSomethingDelegate(server.DoSomething);
d.BeginInvoke(n, userState, __DoSomethingResultsCallback, __DoSomethingCompletedCallback, userState);
}
#endregion
#region Public Events
public event ProgressChangedEventHandler DoSomethingProgressChanged;
public event DoSomethingCompletedEventHandler DoSomethingCompleted;
#endregion
#region Public Properties
[Browsable(false)]
public IServer Server
{
get
{
return server;
}
set
{
if (server == null)
{
server = value;
}
else
{
throw new InvalidOperationException("AsyncHelper.Server can only be set once.");
}
}
}
#endregion
#region Implementation
#region Callback Methods (Public because of Remoting restrictions.)
public void __DoSomethingResultsCallback(int? result, int progressPercentage, object userState)
{
OperationState opState = null;
lock (userStateToOperationState)
{
opState = userStateToOperationState[userState];
}
if (opState != null)
{
opState.Result = result;
opState.Operation.Post(OnDoSomethingProgressChanged, new ProgressChangedEventArgs(progressPercentage, userState));
}
}
private void __DoSomethingCompletedCallback(IAsyncResult iar)
{
AsyncResult ar = (AsyncResult) iar;
DoSomethingDelegate d = (DoSomethingDelegate) ar.AsyncDelegate;
Exception error = null;
try
{
d.EndInvoke(iar);
}
catch (Exception ex)
{
error = ex;
}
OperationState opState = null;
lock (userStateToOperationState)
{
opState = userStateToOperationState[iar.AsyncState];
userStateToOperationState.Remove(iar.AsyncState);
}
if (opState != null)
{
opState.Operation.PostOperationCompleted(OnDoSomethingCompleted, new DoSomethingCompletedEventArgs(
error,
opState.Result == null,
opState.Operation.UserSuppliedState,
opState.Result));
}
}
#endregion
#region Protected Methods
protected virtual void OnDoSomethingProgressChanged(object arg)
{
if (DoSomethingProgressChanged != null)
{
DoSomethingProgressChanged(server, (ProgressChangedEventArgs) arg);
}
}
protected virtual void OnDoSomethingCompleted(object arg)
{
if (DoSomethingCompleted != null)
{
DoSomethingCompleted(server, (DoSomethingCompletedEventArgs) arg);
}
}
#endregion
#region Private Fields
private Dictionary<object, OperationState> userStateToOperationState = new Dictionary<object, OperationState>();
private IServer server;
#endregion
#region Private Types
private class OperationState
{
public OperationState(int arg, object userState)
{
this.Operation = AsyncOperationManager.CreateOperation(userState);
this.Argument = arg;
this.result = null;
this.progressPercentage = 0;
}
#region Public Fields and Properties
public readonly AsyncOperation Operation;
public readonly int Argument;
public int? Result
{
get
{
return result;
}
set
{
if (result == null)
{
result = value;
}
}
}
public int ProgressPercentage
{
get
{
return progressPercentage;
}
set
{
if (value < 0 || 100 < value)
{
throw new ArgumentOutOfRangeException("ProgressPercentage", value, "ProgressPercentage must be in the range [0, 100].");
}
else
{
progressPercentage = value;
}
}
}
#endregion
#region Private Fields and Properties
private int? result;
private int progressPercentage;
#endregion
}
#endregion
#region Private Delegates
private delegate void DoSomethingDelegate(int n, object userState, DoSomethingResultsCallback resultsCallback);
#endregion
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I got my B.Sc. in Mathematics and Computer Science from Tel Aviv University in 1997. Since then I have developed software in UNIX, Win32 and .NET. I currently live in Haifa.