Skip to content

Instantly share code, notes, and snippets.

@micdenny
Created June 18, 2014 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micdenny/f3db9e97e30d2284f846 to your computer and use it in GitHub Desktop.
Save micdenny/f3db9e97e30d2284f846 to your computer and use it in GitHub Desktop.
CastleWcfFacilityPolicyCatchAsync
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading;
using System.Threading.Tasks;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace TestClient
{
internal class Program
{
private static void Main(string[] args)
{
Console.Write("Test sync (1 default) or async (2): ");
var test = Console.ReadLine();
var returnFaults = new ServiceDebugBehavior
{
IncludeExceptionDetailInFaults = true,
HttpHelpPageEnabled = true
};
var serverContainer = new WindsorContainer()
.AddFacility<WcfFacility>()
.Register(
Component.For<IServiceBehavior>().Instance(returnFaults),
Component.For<ITestService>()
.ImplementedBy<TestService>()
.AsWcfService(new DefaultServiceModel()
.AddBaseAddresses("http://localhost:4455")
.PublishMetadata(mex => mex.EnableHttpGet())
.AddEndpoints(WcfEndpoint
.ForContract<ITestService>()
.BoundTo(new BasicHttpBinding())))
);
var clientContainer = new WindsorContainer()
.AddFacility<WcfFacility>()
.Register(
Component.For<CatchAsyncPolicy>(),
Component.For<ITestService>()
.AsWcfClient(WcfEndpoint.ForContract<ITestService>()
.BoundTo(new BasicHttpBinding())
.At("http://localhost:4455"))
);
bool stopped = false;
var testService = clientContainer.Resolve<ITestService>();
var t = new Thread(() =>
{
while (!stopped)
{
if (test == "2")
{
try
{
Console.WriteLine("Async Call: testService.BeginWcfCall(c => c.GetRandomValue(), call =>");
//var ac = testService.BeginWcfCall(c => c.GetRandomValue(), call =>
//{
// try
// {
// var rn = call.End();
// Console.WriteLine("Async Reply: random number: {0}", rn);
// }
// catch (Exception e)
// {
// Console.WriteLine("Async Error: {0}", e.Message);
// }
//}, null);
//ac.AsyncWaitHandle.WaitOne();
var task = testService
.CallAsync(c => c.GetRandomValue())
.ContinueWith(precTask =>
{
if (precTask.Exception == null)
{
var rn = precTask.Result;
Console.WriteLine("Async Reply: random number: {0}", rn);
}
else
{
Console.WriteLine("Async Error: {0}", precTask.Exception.InnerException.Message);
}
});
task.Wait();
}
catch (Exception ex)
{
Console.WriteLine("BeginWcfCall Error: {0}", ex.Message);
}
}
else
{
// test == "1"
try
{
Console.WriteLine("Call: testService.GetRandomValue()");
var rn = testService.GetRandomValue();
Console.WriteLine("Reply: random number: {0}", rn);
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
}
if (!stopped) Thread.Sleep(2000);
}
});
t.Start();
Console.WriteLine("Press enter to CLOSE the service...");
Console.ReadLine();
serverContainer.Dispose();
Console.WriteLine("Press enter to exit the application...");
Console.ReadLine();
stopped = true;
t.Join();
clientContainer.Release(testService);
clientContainer.Dispose();
}
}
public class CatchAsyncPolicy : AbstractWcfPolicy
{
public override void Apply(WcfInvocation wcfInvocation)
{
var refresh = false;
try
{
Console.WriteLine("Proceed: wcfInvocation.Refresh(false).Proceed()");
wcfInvocation.Refresh(false).Proceed();
//var result = wcfInvocation.ReturnValue;
//var task = result as Task;
//if (task != null)
//{
// Console.WriteLine("The call is async.");
//}
}
catch (Exception ex) // Catch everything just for testing purpose
{
refresh = true;
Console.WriteLine("Proceed Exception!");
}
if (refresh)
{
Console.WriteLine("Retry-Proceed: wcfInvocation.Refresh(true).Proceed()");
wcfInvocation.Refresh(true).Proceed();
}
}
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
int GetRandomValue();
[OperationContract]
int MultiplyValues(int a, int b);
[OperationContract]
void Execute();
}
public class TestService : ITestService
{
public int GetRandomValue()
{
var random = new Random();
return random.Next();
}
public int MultiplyValues(int a, int b)
{
return a * b;
}
public void Execute()
{
Trace.WriteLine("Call Execute()");
}
}
public static class WcfClientExtension
{
public static Task<TResult> CallAsync<TProxy, TResult>(this TProxy proxy, Func<TProxy, TResult> method)
{
return Task.Run(() => method(proxy));
}
public static Task CallAsync<TProxy>(this TProxy proxy, Action<TProxy> method)
{
return Task.Run(() => method(proxy));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment