/*
Remoting 异步队列实现,流程如下
1.并发若干客户端程序通过调用 RemotingQueue Server 提供的公开远程方法 Enqueue 将数据元素入队尾
2.RemotingQueue Server 发现队列不为空,则并发若干线程陆续 Dequeue 队首数据元素并处理
注意:
1.队列的数据元素定义需自行实现
2.对出列数据元素的处理程序需自行实现
不受 Remoting 生命周期租约过期的约束
*/
//AsyncQueue.cs
namespace Microshaoft
{
using System;
using System.Threading;
using System.Collections.Generic;
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 delegate void ExceptionEventHandler(Exception exception);
public event ExceptionEventHandler OnException;
private Queue<T> _queue = new Queue<T>();
private static object _SyncLockObject = new object();
private int _concurrentThreadsCount = 0; //Microshaoft 用于控制并发线程数
private volatile bool _queueRuning = false;
private int _maxConcurrentThreadsCount = 1; //Microshaoft 允许并发出列处理线程数为 1
public int MaxConcurrentThreadsCount
{
set
{
_maxConcurrentThreadsCount = value;
}
get
{
return _maxConcurrentThreadsCount;
}
}
private long _EnqueueCount = 0; //入列计数器
public long EnqueueCount
{
get
{
return _EnqueueCount;
}
}
private long _DequeueCount = 0; //出列计数器
public long DequeueCount
{
get
{
return _DequeueCount;
}
}
//Microshaoft 服务启动后可立即开启新的线程调用此方法(死循环)
private void QueueRun() //Microshaoft ThreadStart
{
if (!_queueRuning)
{
_queueRuning = true;
lock (_SyncLockObject)
{
ThreadStart ts = new ThreadStart(QueueRunThreadProcess);
Thread t = new Thread(ts);
t.Name = "QueueRunThreadProcess";
t.Start();
}
}
}
public int Count
{
get
{
return _queue.Count;
}
}
public int ConcurrentThreadsCount
{
get
{
return _concurrentThreadsCount;
}
}
private void QueueRunThreadProcess()
{
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "Queue Runing Start ..."
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
while (_queue.Count > 0) //Microshaoft 死循环
{
T element = null;
int threadID = -1;
lock (_SyncLockObject)
{
if (_concurrentThreadsCount < _maxConcurrentThreadsCount)
{
if (_queue.Count > 0)
{
Interlocked.Increment(ref _concurrentThreadsCount);
threadID = _concurrentThreadsCount;
if (_concurrentThreadsCount >= _maxConcurrentThreadsCount)
{
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "Threads is Full!"
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
}
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "Threads ++ !"
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
element = _queue.Dequeue();
}
}
}
if (element != null)
{
//Microshaoft ThreadPool.QueueUserWorkelement(new WaitCallback(OnDequeueThreadProcess), element);
ThreadProcessState tps = new ThreadProcessState();
tps.element = element;
tps.Sender = this;
Thread t = new Thread(new ThreadStart(tps.ThreadProcess));
t.Name = string.Format("ConcurrentThread[{0}]", threadID);
t.Start();
}
}
_queueRuning = false;
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "Queue Runing Stopped!"
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
}
public void Enqueue(T element)
{
try
{
lock (_SyncLockObject) //还算并发吗?
{
_queue.Enqueue(element);
}
Interlocked.Increment(ref _EnqueueCount);
}
catch (Exception e)
{
if (OnException != null)
{
OnException(e);
}
}
if (!_queueRuning)
{
QueueRun();
}
}
private void OnDequeueThreadProcess(T element)
{
try
{
if (OnDequeue != null)
{
OnDequeue(element);
}
Interlocked.Increment(ref _DequeueCount);
DequeueProcess();
}
catch (Exception e)
{
if (OnException != null)
{
OnException(e);
}
}
finally
{
Interlocked.Decrement(ref _concurrentThreadsCount);
if (_concurrentThreadsCount == 0)
{
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "All Threads Finished!"
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
}
if (OnQueueLog != null)
{
OnQueueLog
(
string.Format
(
"{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
, "Threads -- !"
, _concurrentThreadsCount
, _queue.Count
, Thread.CurrentThread.Name
)
);
}
}
}
private void DequeueProcess()
{
while (_queue.Count > 0)
{
T element = null;
lock (_SyncLockObject)
{
if (_queue.Count > 0)
{
element = _queue.Dequeue();
}
}
if (element != null)
{
if (OnDequeue != null)
{
OnDequeue(element);
}
Interlocked.Increment(ref _DequeueCount);
}
}
}
private class ThreadProcessState
{
private AsyncQueue<T> _sender;
public AsyncQueue<T> Sender
{
get
{
return _sender;
}
set
{
_sender = value;
}
}
private T _element;
public T element
{
get
{
return _element;
}
set
{
_element = value;
}
}
public void ThreadProcess()
{
_sender.OnDequeueThreadProcess(_element);
}
}
}
}
namespace Test
{
using System;
using System.Threading;
using Microshaoft;
public class Class1
{
static AsyncQueue<Item> _queue;
public static void Main1()
{
Console.Title = "Client";
Console.WriteLine(Environment.Version.ToString());
Class1 a = new Class1();
a.Run();
Console.ReadLine();
}
public void Run()
{
_queue = new AsyncQueue<Item>();
_queue.OnDequeue += new AsyncQueue<Item>.QueueEventHandler(_queue_OnDequeue);
_queue.OnQueueLog += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
_queue.OnException += new AsyncQueue<Item>.ExceptionEventHandler(_queue_OnException);
_queue.MaxConcurrentThreadsCount = 200;
Thread t = new Thread(new ThreadStart(ConsoleMonitor));
t.Start();
//Microshaoft 以下是耗时的主程序
for (int i = 0; i < 1000; i++)
{
Thread x = new Thread(new ThreadStart(ThreadProcess));
x.Start();
}
}
public void ConsoleMonitor()
{
Console.WriteLine("press any key to check queue status ...");
while (Console.ReadLine() != "q")
{
Console.WriteLine
(
"Queue elements: {0},Threads count: {1},{2},{3}"
, _queue.Count
, _queue.ConcurrentThreadsCount
, _queue.EnqueueCount
, _queue.DequeueCount
);
}
}
void _queue_OnException(Exception e)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(e.Message);
Console.ResetColor();
}
void _queue_OnQueueLog(string logMessage)
{
/// Console.WriteLine(logMessage);
}
void _queue_OnDequeue(Item element)
{
/// DateTime DequeueBeginTime = DateTime.Now;
/// DateTime DequeueEndTime = DateTime.Now;
/// Console.WriteLine
/// (
/// "QueueRemainCount {0}, Enqueue {1}, Dequeue {2},[{3}], End {4},[{5}],[{6}]"
/// , _queue.Count
/// , element.EnqueueTime
/// , DequeueBeginTime
/// , (DequeueBeginTime.Ticks - element.EnqueueTime.Ticks) / 10000 /1000
/// , DequeueEndTime
/// , (DequeueEndTime.Ticks - DequeueBeginTime.Ticks) / 10000 /1000
/// , _queue.ConcurrentThreadsCount
/// );
/// Console.WriteLine(element.EnqueueTime);
Thread.Sleep(1);
}
public void ThreadProcess()
{
for (int i = 0; i < 1000; i++)
{
Item x = new Item();
DateTime EnqueueTime = DateTime.Now;
x.Name = EnqueueTime.ToString();
x.EnqueueTime = EnqueueTime;
_queue.Enqueue(x);
/// Console.WriteLine
/// (
/// "Enqueue: {0},[{1}]"
/// , EnqueueTime
/// , (DateTime.Now.Ticks - EnqueueTime.Ticks) / 10000 / 1000
/// );
}
}
}
}
namespace Test
{
using System;
public class Item
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private DateTime _EnqueueTime;
public DateTime EnqueueTime
{
get
{
return _EnqueueTime;
}
set
{
_EnqueueTime = value;
}
}
}
}
//Server.cs
namespace Microshaoft
{
using System;
using Microshaoft.RemotingObjects.Share;
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.OnQueueLog += new AsyncQueue<Item>.QueueLogEventHandler(_queue_OnQueueLog);
_queue.OnException += new AsyncQueue<Item>.ExceptionEventHandler(_queue_OnException);
_queue.MaxConcurrentThreadsCount = 200;
}
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;
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());
}
}
}
namespace Microshaoft.RemotingObjects.Server
{
using System;
using System.Threading;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;
using System.ServiceProcess;
using System.ComponentModel;
using System.Configuration.Install;
using System.Security.Principal;
using Microshaoft.RemotingObjects;
using Microshaoft.RemotingObjects.Share;
using Microshaoft.Win32;
using Microshaoft;
public class ServiceHost : ServiceBase
{
///// <summary>
/// 应用程序的主入口点。
/// </summary>
//[STAThread]
public static readonly string serviceName = "RemotingAsyncQueueService";
private static AsyncQueueProcessor _asyncQueueProcessor;
public static AsyncQueueProcessor AsyncQueueProcessor
{
get
{
return _asyncQueueProcessor;
}
}
static void Main(string[] args)
{
//Microshaoft
//Microshaoft TODO: 在此处添加代码以启动应用程序
//Microshaoft
ServiceHost service = new ServiceHost();
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 = "Server"; //不能以服务运行
Console.WriteLine("Console");
service.OnStart(null);
Console.ReadLine();
return;
}
Console.WriteLine("Service");
ServiceBase.Run(service);
if (needFreeConsole)
{
Console.WriteLine("Free Console ...");
NativeMethods.FreeConsole();
}
}
public ServiceHost()
{
CanPauseAndContinue = true;
ServiceName = ServiceHost.serviceName;
}
protected override void OnStart(string[] args)
{
Console.WriteLine(Environment.Version.ToString());
AsyncQueue<Item> queue = new AsyncQueue<Item>();
_asyncQueueProcessor = new AsyncQueueProcessor(queue);
RemotingHelper.StartRemoting<RemotingAsyncQueue>
(
"queueurl"
, 8080
);
Console.WriteLine("Server . , Press Enter key to exit.");
}
}
[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 = ServiceHost.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.RemotingObjects
{
using System;
using System.IO;
using System.Net;
using System.Web;
using System.Text;
using System.Threading;
using System.Configuration;
using System.Collections.Generic;
using Microshaoft;
using Microshaoft.RemotingObjects.Share;
using Microshaoft.RemotingObjects.Server;
public class RemotingAsyncQueue : MarshalByRefObject
{
public void Enqueue(Item item)
{
//Microshaoft 队列的数据元素定义需自行实现 Item
ServiceHost.AsyncQueueProcessor.Enqueue(item);
}
}
}
//=============================================================
//===============================================
// Share.cs
//Server、Client 均需引用此 share.dll
//C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library share.cs
//TO DO
//队列的数据元素定义需自行实现,示例如下:
namespace Microshaoft.RemotingObjects.Share
{
using System;
[Serializable]
public class Item
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private DateTime _EnqueueTime;
public DateTime EnqueueTime
{
get
{
return _EnqueueTime;
}
set
{
_EnqueueTime = value;
}
}
}
}
// remoting helper
//Share.cs
namespace Microshaoft
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;
using System.Text;
public static class RemotingHelper
{
public static void StartRemoting
(
Type RemotingType
, string Url
, int Port
)
{
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary ht = new Hashtable();
ht["port"] = Port;
TcpChannel tc = new TcpChannel(ht, null, provider);
ChannelServices.RegisterChannel(tc, false);
RemotingConfiguration.RegisterWellKnownServiceType(RemotingType, Url, WellKnownObjectMode.Singleton);
Console.WriteLine("Remoting Object Started ...");
}
public static void StartRemoting<T>
(
string Url
, int Port
)
{
StartRemoting(typeof(T), Url, Port);
}
public static T GetRemotingLocalClientProxyObject<T>
(
string Url
)
{
return (T) Activator.GetObject
(
typeof(T)
, Url
//, "tcp://127.0.0.1:8080/queueUrl"
);
}
}
}
//============================================================================
//============================================
// Client.cs
//C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe client.cs /r:share.dll
namespace Microshaoft.RemotingObjects.Client
{
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;
using System.Threading;
using Microshaoft.RemotingObjects;
using Microshaoft.RemotingObjects.Share;
public class Class1
{
static RemotingAsyncQueue _queue;
public static void Main()
{
Console.Title = "Client";
Console.WriteLine(Environment.Version.ToString());
Class1 a = new Class1();
a.Run();
}
public void Run()
{
_queue = RemotingHelper.GetRemotingLocalClientProxyObject<RemotingAsyncQueue>("tcp://127.0.0.1:8080/queueUrl");
//Microshaoft 以下是耗时的主程序
for (int i = 0; i < 50; i++)
{
Thread x = new Thread(new ThreadStart(ThreadProcess));
x.Start();
}
}
public void ThreadProcess()
{
for (int i = 0; i < 800; i++)
{
Item x = new Item();
DateTime EnqueueTime = DateTime.Now;
x.Name = EnqueueTime.ToString();
x.EnqueueTime = EnqueueTime;
_queue.Enqueue(x);
Console.WriteLine
(
"Enqueue: {0},[{1}]"
, EnqueueTime
, (DateTime.Now.Ticks - EnqueueTime.Ticks)/10000/1000
);
}
}
}
}
//Microshaoft =========================================
//Microshaoft Remoting Object Client Local Proxy
namespace Microshaoft.RemotingObjects
{
using System;
using Microshaoft.RemotingObjects.Share;
public interface RemotingAsyncQueue
{
void Enqueue(Item item);
}
}