|
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Xml;
using System.Transactions;
using System.ServiceModel;
using System.ServiceModel.MsmqIntegration;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Net.Security;
using RKiss.NullChannelLib;
namespace Host4
{
#region Contract
[ServiceContract(SessionMode=SessionMode.Required)]
//[ServiceContract]
public interface ITest
{
//[OperationContract(IsOneWay = true, IsInitiating=true)]
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Ping(int value);
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
string Ping2(int value);
}
[ServiceContract]
[ServiceKnownType(typeof(string))]
public interface ITestQueue
{
[OperationContract(IsOneWay = true, Action = "*")]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Show(MsmqMessage<string> msg);
}
#endregion
#region Service
[ServiceBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single)]
public class Test : ITest
{
const string strQueueName = @".\private$\test";
[OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)]
public void Ping(int value)
{
//Thread.Sleep(4000);
TransactionStatus txstatus = TransactionStatus.InDoubt;
if (Transaction.Current != null)
txstatus = Transaction.Current.TransactionInformation.Status;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("\n[tid={0}, tx={1}] *** PING Service: {2} ***\n", Thread.CurrentThread.GetHashCode(), txstatus, value);
Console.ResetColor();
//Thread.Sleep(5000);
// for test purpose we are using MSMQ resource manager
System.Messaging.MessageQueue mq = new System.Messaging.MessageQueue(strQueueName);
mq.Send("This is a test message", value.ToString(), System.Messaging.MessageQueueTransactionType.Automatic);
//if(state == 2)
//throw new Exception("M A N U A L L Y A B O R T E D");
}
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public string Ping2(int value)
{
TransactionStatus txstatus = TransactionStatus.InDoubt;
if (Transaction.Current != null)
txstatus = Transaction.Current.TransactionInformation.Status;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("\n[tid={0}, tx={1}] *** PING_2 Service: {2} ***\n", Thread.CurrentThread.GetHashCode(), txstatus, value);
Console.ResetColor();
string retval = string.Format("[{0}, {1}, Hello from tid={2}]", DateTime.Now.ToShortTimeString(), value, Thread.CurrentThread.GetHashCode());
//using (DependentTransaction dtx = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete))
{
// for test purpose we are using MSMQ resource manager
System.Messaging.MessageQueue mq = new System.Messaging.MessageQueue(strQueueName);
mq.Send(retval, value.ToString(), System.Messaging.MessageQueueTransactionType.Automatic);
//throw new Exception("M A N U A L L Y A B O R T E D");
//dtx.Complete();
}
//Thread.Sleep(62000);
return retval;
}
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single)]
public class TestQueue : ITestQueue
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void Show(MsmqMessage<string> msg)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("\n*** Queue: Label[{0}], Body[{1}] ***\n", msg.Label, msg.Body);
Console.ResetColor();
}
}
#endregion
#region tester
class Program4
{
const string strQueueName = @".\private$\test";
[MTAThread]
static void Main(string[] args)
{
//
ServiceHost host = null;
ServiceHost host2 = null;
try
{
// Check and Create the transacted MSMQ queue
if (!System.Messaging.MessageQueue.Exists(strQueueName))
{
Console.WriteLine("\nCreating a transactional private queue 'test' +++\n");
System.Messaging.MessageQueue.Create(strQueueName, true);
}
using (host = new ServiceHost(typeof(Test)))
using (host2 = new ServiceHost(typeof(TestQueue)))
{
host.Open();
host2.Open();
Thread.Sleep(2000);
Console.WriteLine("\npress any key to continue ...\n");
Console.ReadLine();
double totalTime = 0;
for (int ii = 0; ii < 1000; ii++)
{
// timestamp
DateTime startDT = DateTime.Now;
// action
worker(ii, "gaga");
// done
double delta = (DateTime.Now - startDT).TotalMilliseconds;
totalTime += delta;
Console.WriteLine("\n[{0}, {1:###.###}ms] +++ press any key to continue +++\n", ii, (DateTime.Now - startDT).TotalMilliseconds);
Console.ReadLine();
}
Console.WriteLine("\n[~time = {0:###.###}ms] +++ press any key to close a ServiceHost +++\n", totalTime / 1000);
Console.ReadLine();
host.Close();
host2.Close();
}
}
catch (CommunicationException ex)
{
if (host != null)
host.Abort();
if (host2 != null)
host2.Abort();
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\n" + ex.Message);
Console.ResetColor();
Console.ReadLine();
}
catch (Exception ex)
{
if (host != null)
host.Abort();
if (host2 != null)
host2.Abort();
Console.WriteLine("\n" + ex);
Console.ReadLine();
}
finally
{
Console.WriteLine("\n*** press any key to exit ... ***\n");
Console.ReadLine();
}
}
internal static void worker(int loop, string name)
{
//ThreadPool.QueueUserWorkItem(delegate
//{
ChannelFactory<ITest> factory = null;
try
{
factory = new ChannelFactory<ITest>(name);
ITest channel = factory.CreateChannel();
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
string response = string.Empty;
response = channel.Ping2(loop);
//channel.Ping(loop);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(string.Format("[{0}, {1}]: {2}, tid={3}\n", loop, name, response, Thread.CurrentThread.GetHashCode()));
Console.ResetColor();
//Thread.Sleep(1000);
Console.WriteLine("\n+++ Press 'a' to abort or any key to finish a transaction. Timeout = 60sec. +++\n");
ConsoleKeyInfo ki = Console.ReadKey();
if (ki.Key == ConsoleKey.A)
{
throw new Exception("M A N U A L Y A B O R T E D");
}
ts.Complete();
}
((IChannel)channel).Close();
factory.Close();
}
catch (Exception ex)
{
if (factory != null) factory.Abort();
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\n" + ex.Message);
Console.ResetColor();
}
//});
}
}
#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.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.