//AsyncQueue.cs
#define c4 //C# 4.0+
//#define c2
namespace Microshaoft
{
using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
#if c4
using System.Collections.Concurrent;
#endif
using Microshaoft;
public class AsyncQueue<T>
where T : class
{
public delegate void QueueEventHandler(T element);
public event QueueEventHandler OnDequeue;
public delegate void QueueLogEventHandler(string logMessage);
//public event QueueLogEventHandler OnQueueLog;
public event QueueLogEventHandler OnQueueRunningThreadStart;
public event QueueLogEventHandler OnQueueRunningThreadEnd;
public event QueueLogEventHandler OnDequeueThreadStart;
public event QueueLogEventHandler OnDequeueThreadEnd;
public event QueueLogEventHandler OnDequeueAllThreadsEnd;
public delegate void ExceptionEventHandler(Exception exception);
public event ExceptionEventHandler OnException;
#if c2
private Queue<T> _queue = new Queue<T>();
#elif c4
private ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();
#endif
private object _syncQueueLockObject = new object();
//private object _syncQueueRunningLockObject = new object();
private long _isQueueRunning = 0;
private long _concurrentDequeueThreadsCount = 0; //Microshaoft 用于控制并发线程数
private PerformanceCounter _enqueuePerformanceCounter;
private PerformanceCounter _dequeuePerformanceCounter;
private PerformanceCounter _dequeueProcessedPerformanceCounter;
private PerformanceCounter _queueLengthPerformanceCounter;
private PerformanceCounter _dequeueThreadStartPerformanceCounter;
private PerformanceCounter _dequeueThreadEndPerformanceCounter;
private PerformanceCounter _dequeueThreadsCountPerformanceCounter;
private PerformanceCounter _queueRunningThreadStartPerformanceCounter;
private PerformanceCounter _queueRunningThreadEndPerformanceCounter;
private PerformanceCounter _queueRunningThreadsCountPerformanceCounter;
private bool _isAttachedPerformanceCounters = false;
public void AttachPerformanceCounters(string instanceNamePrefix)
{
string category = "Microshaoft AsyncConurrentQueue Counters";
string counter = string.Empty;
Process process = Process.GetCurrentProcess();
//int processID = 0;//process.Id;
string processName = process.ProcessName;
//string processStartTime = "";//process.StartTime;
string instanceName = string.Empty;
instanceName = string.Format
(
"{0}-{1}"
, instanceNamePrefix
, processName
//, processID
//, processStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")
);
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
if (PerformanceCounterCategory.Exists(category))
{
PerformanceCounterCategory.Delete(category);
}
CounterCreationData ccd = null;
counter = "EnqueueCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "DequeueCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "QueueLengthCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "DequeueProcessedCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "DequeueThreadStartCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "DequeueThreadEndCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "DequeueThreadsCountCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "QueueRunningThreadStartCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "QueueRunningThreadEndCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
counter = "QueueRunningThreadsCountCounter";
ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64);
ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64));
PerformanceCounterCategory.Create
(
category,
string.Format("{0} Category Help.", category),
PerformanceCounterCategoryType.MultiInstance,
ccdc
);
counter = "EnqueueCounter";
_enqueuePerformanceCounter = new PerformanceCounter();
_enqueuePerformanceCounter.CategoryName = category;
_enqueuePerformanceCounter.CounterName = counter;
_enqueuePerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_enqueuePerformanceCounter.InstanceName = instanceName;
_enqueuePerformanceCounter.ReadOnly = false;
_enqueuePerformanceCounter.RawValue = 0;
counter = "DequeueCounter";
_dequeuePerformanceCounter = new PerformanceCounter();
_dequeuePerformanceCounter.CategoryName = category;
_dequeuePerformanceCounter.CounterName = counter;
_dequeuePerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_dequeuePerformanceCounter.InstanceName = instanceName;
_dequeuePerformanceCounter.ReadOnly = false;
_dequeuePerformanceCounter.RawValue = 0;
counter = "DequeueProcessedCounter";
_dequeueProcessedPerformanceCounter = new PerformanceCounter();
_dequeueProcessedPerformanceCounter.CategoryName = category;
_dequeueProcessedPerformanceCounter.CounterName = counter;
_dequeueProcessedPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_dequeueProcessedPerformanceCounter.InstanceName = instanceName;
_dequeueProcessedPerformanceCounter.ReadOnly = false;
_dequeueProcessedPerformanceCounter.RawValue = 0;
counter = "QueueLengthCounter";
_queueLengthPerformanceCounter = new PerformanceCounter();
_queueLengthPerformanceCounter.CategoryName = category;
_queueLengthPerformanceCounter.CounterName = counter;
_queueLengthPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_queueLengthPerformanceCounter.InstanceName = instanceName;
_queueLengthPerformanceCounter.ReadOnly = false;
_queueLengthPerformanceCounter.RawValue = 0;
counter = "DequeueThreadStartCounter";
_dequeueThreadStartPerformanceCounter = new PerformanceCounter();
_dequeueThreadStartPerformanceCounter.CategoryName = category;
_dequeueThreadStartPerformanceCounter.CounterName = counter;
_dequeueThreadStartPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_dequeueThreadStartPerformanceCounter.InstanceName = instanceName;
_dequeueThreadStartPerformanceCounter.ReadOnly = false;
_dequeueThreadStartPerformanceCounter.RawValue = 0;
counter = "DequeueThreadEndCounter";
_dequeueThreadEndPerformanceCounter = new PerformanceCounter();
_dequeueThreadEndPerformanceCounter.CategoryName = category;
_dequeueThreadEndPerformanceCounter.CounterName = counter;
_dequeueThreadEndPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_dequeueThreadEndPerformanceCounter.InstanceName = instanceName;
_dequeueThreadEndPerformanceCounter.ReadOnly = false;
_dequeueThreadEndPerformanceCounter.RawValue = 0;
counter = "DequeueThreadsCountCounter";
_dequeueThreadsCountPerformanceCounter = new PerformanceCounter();
_dequeueThreadsCountPerformanceCounter.CategoryName = category;
_dequeueThreadsCountPerformanceCounter.CounterName = counter;
_dequeueThreadsCountPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_dequeueThreadsCountPerformanceCounter.InstanceName = instanceName;
_dequeueThreadsCountPerformanceCounter.ReadOnly = false;
_dequeueThreadsCountPerformanceCounter.RawValue = 0;
counter = "QueueRunningThreadStartCounter";
_queueRunningThreadStartPerformanceCounter = new PerformanceCounter();
_queueRunningThreadStartPerformanceCounter.CategoryName = category;
_queueRunningThreadStartPerformanceCounter.CounterName = counter;
_queueRunningThreadStartPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_queueRunningThreadStartPerformanceCounter.InstanceName = instanceName;
_queueRunningThreadStartPerformanceCounter.ReadOnly = false;
_queueRunningThreadStartPerformanceCounter.RawValue = 0;
counter = "QueueRunningThreadEndCounter";
_queueRunningThreadEndPerformanceCounter = new PerformanceCounter();
_queueRunningThreadEndPerformanceCounter.CategoryName = category;
_queueRunningThreadEndPerformanceCounter.CounterName = counter;
_queueRunningThreadEndPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_queueRunningThreadEndPerformanceCounter.InstanceName = instanceName;
_queueRunningThreadEndPerformanceCounter.ReadOnly = false;
_queueRunningThreadEndPerformanceCounter.RawValue = 0;
counter = "QueueRunningThreadsCountCounter";
_queueRunningThreadsCountPerformanceCounter = new PerformanceCounter();
_queueRunningThreadsCountPerformanceCounter.CategoryName = category;
_queueRunningThreadsCountPerformanceCounter.CounterName = counter;
_queueRunningThreadsCountPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
_queueRunningThreadsCountPerformanceCounter.InstanceName = instanceName;
_queueRunningThreadsCountPerformanceCounter.ReadOnly = false;
_queueRunningThreadsCountPerformanceCounter.RawValue = 0;
_isAttachedPerformanceCounters = true;
}
private int _maxConcurrentThreadsCount = 1; //Microshaoft 允许并发出列处理线程数为 1
public int MaxConcurrentThreadsCount
{
set
{
_maxConcurrentThreadsCount = value;
}
get
{
return _maxConcurrentThreadsCount;
}
}
//Microshaoft 服务启动后可立即开启新的线程调用此方法(死循环)
private void QueueRun() //Microshaoft ThreadStart
{
if (Interlocked.Read(ref _concurrentDequeueThreadsCount) < _maxConcurrentThreadsCount)
{
if (Interlocked.CompareExchange(ref _isQueueRunning, 0, 1) == 0)
{
ThreadStart ts = new ThreadStart(QueueRunThreadProcess);
Thread t = new Thread(ts);
t.Name = "QueueRunningThreadProcess";
t.Start();
}
}
}
public int Count
{
get
{
return _queue.Count;
}
}
public long ConcurrentThreadsCount
{
get
{
return _concurrentDequeueThreadsCount;
}
}
private void QueueRunThreadProcess()
{
if (_isAttachedPerformanceCounters)
{
_queueRunningThreadStartPerformanceCounter.Increment();
_queueRunningThreadsCountPerformanceCounter.Increment();
}
if (OnQueueRunningThreadStart != null)
{
OnQueueRunningThreadStart
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}({4}) at {5}"
, "Queue Running Start ..."
, _concurrentDequeueThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
, Thread.CurrentThread.ManagedThreadId
, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
)
);
}
#if c2
while ((_queue.Count > 0)) //Microshaoft 死循环
#elif c4
while (!_queue.IsEmpty) //Microshaoft 死循环
#endif
{
int threadID = -1;
{
int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount);
if (r < _maxConcurrentThreadsCount)
{
//if (_queue.Count > 0)
{
r = (int)Interlocked.Increment(ref _concurrentDequeueThreadsCount);
threadID = (int)_concurrentDequeueThreadsCount;
//ThreadProcessState tps = new ThreadProcessState();
//tps.element = element;
//tps.Sender = this;
Thread t = new Thread(new ThreadStart(DequeueThreadProcess));
t.Name = string.Format("ConcurrentDequeueProcessThread[{0}]", threadID);
t.Start();
}
/// else
/// {
/// break;
/// }
}
else
{
break;
}
}
}
//Interlocked.CompareExchange(ref _queueRuning, 0, 1);
if (OnQueueRunningThreadEnd != null)
{
int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount);
OnQueueRunningThreadEnd
(
string.Format
(
"{0} Threads Count {1}, Queue Count {2}, Current Thread: {3}({4}) at {5}"
, "Queue Running Stop ..."
, r
, _queue.Count
, Thread.CurrentThread.Name
, Thread.CurrentThread.ManagedThreadId
, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
)
);
}
if (_isAttachedPerformanceCounters)
{
_queueRunningThreadEndPerformanceCounter.Increment();
_queueRunningThreadsCountPerformanceCounter.Decrement();
}
Interlocked.Exchange(ref _isQueueRunning, 0);
}
public void Enqueue(T element)
{
try
{
#if c2
lock (_syncQueueLockObject) //还算并发吗?
#endif
{
_queue.Enqueue(element);
}
if (_isAttachedPerformanceCounters)
{
_enqueuePerformanceCounter.Increment();
_queueLengthPerformanceCounter.Increment();
}
}
catch (Exception e)
{
if (OnException != null)
{
OnException(e);
}
}
//int r = Interlocked.CompareExchange(ref _queueRuning, 1, 0))
//if (r == 1)
//{
QueueRun();
//}
}
private void DequeueThreadProcess()
{
if (_isAttachedPerformanceCounters)
{
_dequeueThreadStartPerformanceCounter.Increment();
_dequeueThreadsCountPerformanceCounter.Increment();
}
if (OnDequeueThreadStart != null)
{
int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount);
OnDequeueThreadStart
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
, "Threads ++ !"
, r
, _queue.Count
, Thread.CurrentThread.Name
, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
)
);
}
bool queueWasNotEmpty = false;
try
{
#if c2
while (true)
#elif c4
while (!_queue.IsEmpty)
#endif
{
T element = null;
#if c2
lock (_syncQueueLockObject)
{
if (_queue.Count > 0)
{
element = _queue.Dequeue();
}
else
{
//避免QueueRun 死循环
break;
}
}
#elif c4
if (_queue.TryDequeue(out element))
{
#elif c2
if (element != null)
{
#endif
if (!queueWasNotEmpty)
{
queueWasNotEmpty = true;
}
if (_isAttachedPerformanceCounters)
{
_dequeuePerformanceCounter.Increment();
_queueLengthPerformanceCounter.Decrement();
}
if (OnDequeue != null)
{
OnDequeue(element);
}
if (_isAttachedPerformanceCounters)
{
_dequeueProcessedPerformanceCounter.Increment();
}
#if c2
}
#elif c4
}
}
#endif
}
catch (Exception e)
{
if (OnException != null)
{
OnException(e);
}
}
finally
{
int r = (int)Interlocked.Decrement(ref _concurrentDequeueThreadsCount);
if (OnDequeueThreadEnd != null)
{
OnDequeueThreadEnd
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
, "Threads--"
, r
, _queue.Count
, Thread.CurrentThread.Name
, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
)
);
}
if (r == 0)
{
if (OnDequeueAllThreadsEnd != null)
{
OnDequeueAllThreadsEnd
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
, "All Threads End"
, r
, _queue.Count
, Thread.CurrentThread.Name
, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
)
);
}
}
if (_isAttachedPerformanceCounters)
{
_dequeueThreadEndPerformanceCounter.Increment();
_dequeueThreadsCountPerformanceCounter.Decrement();
}
if (queueWasNotEmpty)
{
QueueRun(); //死循环???
}
}
}
}
}
namespace Microshaoft
{
using System;
using System.Diagnostics;
public static class PerformanceCounterHelper
{
public static CounterCreationData GetCounterCreationData(string counterName, PerformanceCounterType performanceCounterType)
{
CounterCreationData ccd = new CounterCreationData();
ccd.CounterName = counterName;
ccd.CounterHelp = string.Format("{0} Help", counterName);
ccd.CounterType = performanceCounterType;
return ccd;
}
}
}
//========================================================================================================================================
// Server.cs
namespace Microshaoft.WCF.Services
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Contracts.Services;
using Contracts.Services.Entitys;
using Microshaoft.WCF.Server;
public class AsyncQueueWcfNetNetTcpService : IQueueAble
{
public void Enqueue(Item item)
{
WindowsServiceHost.AsyncQueueProcessor.Enqueue(item);
}
}
}
namespace Microshaoft.WCF.Server
{
using System;
using System.ComponentModel;
using System.ServiceProcess;
using System.Configuration.Install;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microshaoft;
using Microshaoft.Win32;
using Microshaoft.WCF.Services;
using Contracts.Services;
using Contracts.Services.Entitys;
public class WindowsServiceHost : ServiceBase
{
///// <summary>
/// 应用程序的主入口点。
/// </summary>
//[STAThread]
public static readonly string serviceName = "AsyncConcurrentQueueWcfNetTcpService";
private static AsyncQueueProcessor _asyncQueueProcessor;
public static AsyncQueueProcessor AsyncQueueProcessor
{
get
{
return _asyncQueueProcessor;
}
}
static void Main(string[] args)
{
//Microshaoft
//Microshaoft TODO: 在此处添加代码以启动应用程序
//Microshaoft
WindowsServiceHost service = new WindowsServiceHost();
int l = 0;
bool needFreeConsole = false;
if (args != null)
{
l = args.Length;
}
if (l > 0)
{
if (args[0].ToLower() == "/console")
{
needFreeConsole = true;
NativeMethods.AllocConsole();
Console.Title = "Server ...";
Console.WriteLine("Alloc Console ...");
Console.WriteLine("Current User Identity: {0}", WindowsIdentity.GetCurrent().Name);
Console.WriteLine(".Net Framework version: {0}", Environment.Version.ToString());
Console.Title = string.Format
(
"{0} Host Server"
, WindowsServiceHost.serviceName
); //不能以服务运行
Console.WriteLine("Console");
service.OnStart(null);
Console.ReadLine();
return;
}
}
Console.WriteLine("Service");
ServiceBase.Run(service);
if (needFreeConsole)
{
Console.WriteLine("Free Console ...");
NativeMethods.FreeConsole();
}
}
public static ServiceHost _serviceHost;
public WindowsServiceHost()
{
CanPauseAndContinue = true;
ServiceName = WindowsServiceHost.serviceName;
}
protected override void OnStart(string[] args)
{
Console.WriteLine(Environment.Version.ToString());
AsyncQueue<Item> queue = new AsyncQueue<Item>();
queue.AttachPerformanceCounters("Q1");
_asyncQueueProcessor = new AsyncQueueProcessor(queue);
_serviceHost = new ServiceHost(typeof(AsyncQueueWcfNetNetTcpService));
string address = "{0}://localhost{1}/servicemodelsamples/service";
string netTcpUrl = string.Format
(
address
, "net.tcp"
, ":9000"
);
string httpUrl = string.Format
(
address
, "http"
, ":8080"
);
NetTcpBinding binding = new NetTcpBinding();
//binding.Security.Transport.MsmqAuthenticationMode = MsmqAuthenticationMode.None;
//binding.Security.Mode = MsmqIntegrationSecurityMode.None;
_serviceHost.AddServiceEndpoint
(
typeof(IQueueAble)
, binding
, netTcpUrl
);
ServiceMetadataBehavior smb = _serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
//发布元数据
if (smb == null)
{
smb = new ServiceMetadataBehavior();
}
//smb.HttpGetEnabled = true;
//smb.HttpGetUrl = new Uri(httpUrl);
//smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
_serviceHost.Description.Behaviors.Add(smb);
// Add MEX endpoint
_serviceHost.AddServiceEndpoint
(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
netTcpUrl + "/mex"
);
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls = 1000;
stb.MaxConcurrentInstances = 1000;
stb.MaxConcurrentSessions = 1000;
_serviceHost.Description.Behaviors.Add(stb);
_serviceHost.Open();
Console.WriteLine("Wcf Service Host Opened ...");
}
}
[RunInstallerAttribute(true)]
public class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;
public ProjectInstaller()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;
// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = WindowsServiceHost.serviceName;
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}
namespace Microshaoft.Win32
{
using System.Runtime.InteropServices;
public class NativeMethods
{
/// <summary>
/// 启动控制台
/// </summary>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
/// <summary>
/// 释放控制台
/// </summary>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
}
}
namespace Microshaoft
{
using System;
using Contracts.Services.Entitys;
public class AsyncQueueProcessor
{
private AsyncQueue<Item> _queue;
public AsyncQueue<Item> Queue
{
get
{
return _queue;
}
}
public AsyncQueueProcessor(AsyncQueue<Item> queue)
{
_queue = queue;
_queue.OnDequeue += new AsyncQueue<Item>.QueueEventHandler(_queue_OnDequeue);
//_queue.OnDequeueThreadStart += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
_queue.OnDequeueAllThreadsEnd += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
_queue.OnDequeueThreadEnd += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
//_queue.OnQueueRunningThreadStart += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
//_queue.OnQueueRunningThreadEnd += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
_queue.OnException += new AsyncQueue<Item>.ExceptionEventHandler(_queue_OnException);
_queue.MaxConcurrentThreadsCount = 64;
}
public void Enqueue(Item item)
{
_queue.Enqueue(item);
}
void _queue_OnQueueLog(string logMessage)
{
Console.WriteLine(logMessage);
}
void _queue_OnDequeue(Item item)
{
DateTime DequeueBeginTime = DateTime.Now;
/// SqlConnection connection = null;
/// try
/// {
/// connection = new SqlConnection(item.ConnectionString);
/// SqlCommand command = new SqlCommand(item.SqlCommandText, connection);
/// command.CommandType = CommandType.Text;
/// connection.Open();
/// command.ExecuteNonQuery();
/// }
/// catch (Exception e)
/// {
/// Console.WriteLine("Exception on Dequeue Process:{0}{1}", "\r\n", e.ToString());
/// }
/// finally
/// {
/// connection.Close();
/// connection.Dispose();
/// connection = null;
/// }
DateTime DequeueEndTime = DateTime.Now;
Console.WriteLine
(
"QueueRemainCount {0}, Enqueue {1}, Dequeue {2},[{3}], End {4},[{5}],[{6}]"
, _queue.Count
, item.EnqueueTime
, DequeueBeginTime
, (DequeueBeginTime.Ticks - item.EnqueueTime.Ticks) / 10000 / 1000
, DequeueEndTime
, (DequeueEndTime.Ticks - DequeueBeginTime.Ticks) / 10000 / 1000
, _queue.ConcurrentThreadsCount
);
}
void _queue_OnException(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
//================================================================================================================
// Share.cs
namespace Contracts.Services
{
using System.ServiceModel;
using Contracts.Services.Entitys;
[ServiceContract]
public interface IQueueAble
{
[OperationContract]
void Enqueue(Item element);
}
}
namespace Contracts.Services.Entitys
{
using System;
using System.Runtime.Serialization;
[DataContract]
public class Item
{
private DateTime _EnqueueTime;
[DataMember]
public DateTime EnqueueTime
{
get
{
return _EnqueueTime;
}
set
{
_EnqueueTime = value;
}
}
private string _sql;
[DataMember]
public string SqlCommandText
{
get
{
return _sql;
}
set
{
_sql = value;
}
}
private string _connectionString;
[DataMember]
public string ConnectionString
{
get
{
return _connectionString;
}
set
{
_connectionString = value;
}
}
}
}
//=======================================================================================
//=======================================================================================================
///// Client.cs
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.1
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
// "D:\Microsoft.SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\SvcUtil.exe" Share.dll
// "D:\Microsoft.SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\SvcUtil.exe" *.wsdl *.xsd
// "D:\Microsoft.SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\SvcUtil.exe" net.tcp://localhost:9000/servicemodelsamples/service/mex
namespace Contracts.Services.Entitys
{
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Item", Namespace="http://schemas.datacontract.org/2004/07/Contracts.Services.Entitys")]
public partial class Item : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private string ConnectionStringField;
private System.DateTime EnqueueTimeField;
private string SqlCommandTextField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string ConnectionString
{
get
{
return this.ConnectionStringField;
}
set
{
this.ConnectionStringField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.DateTime EnqueueTime
{
get
{
return this.EnqueueTimeField;
}
set
{
this.EnqueueTimeField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string SqlCommandText
{
get
{
return this.SqlCommandTextField;
}
set
{
this.SqlCommandTextField = value;
}
}
}
}
namespace Proxy
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IQueueAble")]
public interface IQueueAble
{
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IQueueAble/Enqueue", ReplyAction="http://tempuri.org/IQueueAble/EnqueueResponse")]
void Enqueue(Contracts.Services.Entitys.Item element);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IQueueAbleChannel : IQueueAble, System.ServiceModel.IClientChannel
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class QueueAbleClient : System.ServiceModel.ClientBase<IQueueAble>, IQueueAble
{
public QueueAbleClient()
{
}
public QueueAbleClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public QueueAbleClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public QueueAbleClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public QueueAbleClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public void Enqueue(Contracts.Services.Entitys.Item element)
{
base.Channel.Enqueue(element);
}
}
}
namespace Microshaoft.WCF.Client
{
using System;
using System.Collections;
using System.Threading;
using System.ServiceModel;
using Proxy;
using Contracts.Services.Entitys;
public class Class1
{
static QueueAbleClient _client;
public static void Main()
{
Console.Title = "Client";
Console.WriteLine(Environment.Version.ToString());
Class1 a = new Class1();
a.Run();
}
public void Run()
{
string address = @"net.tcp://localhost:9000/servicemodelsamples/service";
NetTcpBinding binding = new NetTcpBinding();
_client = new QueueAbleClient(binding, new EndpointAddress(address));
for (int i = 0; i < 20; i++)
{
Thread x = new Thread(new ThreadStart(ThreadProcess));
x.Start();
}
}
public void ThreadProcess()
{
for (int i = 0; i < 1000; i++)
{
Item x = new Item();
DateTime EnqueueTime = DateTime.Now;
x.EnqueueTime = EnqueueTime;
x.SqlCommandText = @"
--==========================
declare @ varchar(10)
set @ = 'aaa'
exec zsp_test @
--==========================
";
x.ConnectionString = "";
_client.Enqueue(x);
Console.WriteLine
(
"Enqueue: {0},[{1}]"
, EnqueueTime
, (DateTime.Now.Ticks - EnqueueTime.Ticks)/10000
);
}
}
}
}
//============================================================================================================================