TimeSpan default_open_timeout, default_close_timeout;
IChannel channel;
IChannelFactory factory;
+ TimeSpan? operation_timeout = null;
+ ChannelFactory channel_factory;
#region delegates
readonly ProcessDelegate _processDelegate;
- delegate object ProcessDelegate (MethodBase method, string operationName, object [] parameters, OperationContext context);
+ delegate object ProcessDelegate (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context);
readonly RequestDelegate requestDelegate;
ChannelFactory channelFactory, EndpointAddress remoteAddress, Uri via)
: this (endpoint.CreateClientRuntime (null), endpoint.Contract, channelFactory.DefaultOpenTimeout, channelFactory.DefaultCloseTimeout, null, channelFactory.OpenedChannelFactory, endpoint.Binding.MessageVersion, remoteAddress, via)
{
+ channel_factory = channelFactory;
}
public ClientRuntimeChannel (ClientRuntime runtime, ContractDescription contract, TimeSpan openTimeout, TimeSpan closeTimeout, IChannel contextChannel, IChannelFactory factory, MessageVersion messageVersion, EndpointAddress remoteAddress, Uri via)
// default values
AllowInitializationUI = true;
- OperationTimeout = TimeSpan.FromMinutes (1);
if (contextChannel != null)
channel = contextChannel;
}
}
- [MonoTODO]
- public TimeSpan OperationTimeout { get; set; }
+ public TimeSpan OperationTimeout {
+ get { return this.operation_timeout ?? (channel_factory != null ? channel_factory.Endpoint.Binding.SendTimeout : DefaultCommunicationTimeouts.Instance.SendTimeout); }
+ set { this.operation_timeout = value; }
+ }
public IOutputSession OutputSession {
get {
public IAsyncResult BeginProcess (MethodBase method, string operationName, object [] parameters, AsyncCallback callback, object asyncState)
{
- return _processDelegate.BeginInvoke (method, operationName, parameters, OperationContext.Current, callback, asyncState);
+ var p = parameters;
+ var retval = _processDelegate.BeginInvoke (method, operationName, true, ref p, OperationContext.Current, callback, asyncState);
+ if (p != parameters)
+ throw new InvalidOperationException ();
+ return retval;
}
public object EndProcess (MethodBase method, string operationName, object [] parameters, IAsyncResult result)
throw new ArgumentNullException ("result");
if (parameters == null)
throw new ArgumentNullException ("parameters");
- // FIXME: the method arguments should be verified to be
- // identical to the arguments in the corresponding begin method.
- return _processDelegate.EndInvoke (result);
+
+ object[] p = parameters;
+ var retval = _processDelegate.EndInvoke (ref p, result);
+ if (p == parameters)
+ return retval;
+
+ Array.Copy (p, parameters, p.Length);
+ return retval;
}
public object Process (MethodBase method, string operationName, object [] parameters, OperationContext context)
+ {
+ var p = parameters;
+ var retval = Process (method, operationName, false, ref p, context);
+ if (p != parameters)
+ throw new InvalidOperationException ();
+ return retval;
+ }
+
+ object Process (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context)
{
var previousContext = OperationContext.Current;
try {
// Inherit the context from the calling thread
OperationContext.Current = context;
- return DoProcess (method, operationName, parameters, context);
+ return DoProcess (method, operationName, isAsync, ref parameters, context);
} catch (Exception ex) {
throw;
} finally {
}
}
- object DoProcess (MethodBase method, string operationName, object [] parameters, OperationContext context)
+ object DoProcess (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context)
{
if (AllowInitializationUI)
DisplayInitializationUI ();
Open ();
if (!od.IsOneWay)
- return Request (od, parameters, context);
+ return Request (od, isAsync, ref parameters, context);
else {
Output (od, parameters, context);
return null;
Send (CreateRequest (op, parameters, context), OperationTimeout);
}
- object Request (OperationDescription od, object [] parameters, OperationContext context)
+ object Request (OperationDescription od, bool isAsync, ref object [] parameters, OperationContext context)
{
ClientOperation op = runtime.Operations [od.Name];
object [] inspections = new object [runtime.MessageInspectors.Count];
for (int i = 0; i < inspections.Length; i++)
runtime.MessageInspectors [i].AfterReceiveReply (ref res, inspections [i]);
- if (op.DeserializeReply)
- return op.Formatter.DeserializeReply (res, parameters);
- else
+ if (!op.DeserializeReply)
return res;
+
+ if (isAsync && od.EndMethod != null) {
+ var endParams = od.EndMethod.GetParameters ();
+ parameters = new object [endParams.Length - 1];
+ }
+
+ return op.Formatter.DeserializeReply (res, parameters);
}
#region Message-based Request() and Send()