¡¾·±ÌåÖÐÎÄ¡¿
¡¾ÉèΪÊ×Ò³¡¿
¡¾¼ÓÈëÊղء¿
µ±Ç°Î»Öãº.Net¼¼ÊõÊ×Ò³ >> C#ÓïÑÔ >> C#£ºÏûÏ¢¶ÓÁÐÓ¦ÓóÌÐò

C#£ºÏûÏ¢¶ÓÁÐÓ¦ÓóÌÐò

2004-10-01 08:26:10  ×÷Õߣº  À´Ô´£º»¥ÁªÍø  ä¯ÀÀ´ÎÊý£º58  ÎÄ×Ö´óС£º¡¾´ó¡¿¡¾ÖС¿¡¾Ð¡¡¿
¼ò½é£ºÕªÒª£º±¾ÎĸÅÊöÒ»ÖÖÓÃÓÚ´¦ÀíÈô¸ÉÏûÏ¢¶ÓÁÐµÄ Windows ·þÎñ½â¾ö·½°¸£¬Öصã½éÉÜ .NET ¿ò¼ÜºÍ C# Ó¦ÓóÌÐò¡£ ÏÂÔØ CSharpMessageService.exe ʾÀýÎļþ (86 KB) Ŀ¼ ¼ò½é .NET ¿ò¼ÜÓ¦ÓóÌÐò Ó¦ÓóÌÐò½á¹¹ ...

ÕªÒª£º±¾ÎĸÅÊöÒ»ÖÖÓÃÓÚ´¦ÀíÈô¸ÉÏûÏ¢¶ÓÁÐµÄ Windows ·þÎñ½â¾ö·½°¸£¬Öصã½éÉÜ .NET ¿ò¼ÜºÍ C# Ó¦ÓóÌÐò¡£

ÏÂÔØ CSharpMessageService.exe ʾÀýÎļþ (86 KB)

Ŀ¼

¼ò½é

.NET ¿ò¼ÜÓ¦ÓóÌÐò

Ó¦ÓóÌÐò½á¹¹

·þÎñÀà

¼ì²âÉ豸

°²×°

×ܽá

²Î¿¼×ÊÁÏ

¼ò½é

Microsoft ½üÆÚÍÆ³öÁËÒ»ÖÖÓÃÓÚÉú³É¼¯³ÉÓ¦ÓóÌÐòµÄÐÂÆ½Ì¨¡ª¡ªMicrosoft .NET ¿ò¼Ü¡£.NET ¿ò¼ÜÔÊÐí¿ª·¢ÈËԱʹÓÃÈκαà³ÌÓïÑÔѸËÙÉú³ÉºÍ²¿Êð Web ·þÎñºÍÓ¦ÓóÌÐò¡£Microsoft Intermediate Language (MSIL) ºÍʵʱ (JIT) ±àÒëÆ÷ʹÕâÖÖ²»ÒÀÀµÓïÑԵĿò¼ÜµÃÒÔʵÏÖ¡£

Óë .NET ¿ò¼ÜÍ¬Ê±ÃæÊÀµÄ»¹ÓÐÒ»ÖÖеıà³ÌÓïÑÔ C#£¨¶Á×÷¡°C sharp¡±£©¡£C# ÊÇÒ»ÖÖ¼òµ¥¡¢ÐÂÓ±¡¢ÃæÏò¶ÔÏóºÍÀàÐͰ²È«µÄ±à³ÌÓïÑÔ¡£ÀûÓà .NET ¿ò¼ÜºÍ C#£¨³ý Microsoft® Visual Basic® ºÍ Managed C++ Ö®Í⣩£¬Óû§¿ÉÒÔ±àд¹¦ÄÜÇ¿´óµÄ Microsoft Windows® ºÍ Web Ó¦ÓóÌÐò¼°·þÎñ¡£±¾ÎÄÌṩÁËÕâÑùµÄÒ»¸ö½â¾ö·½°¸£¬ËüµÄÖØµãÊÇ .NET ¿ò¼ÜºÍ C# ¶ø²»ÊDZà³ÌÓïÑÔ¡£C# ÓïÑԵĽéÉÜ¿ÉÒÔÔÚ¡° C# ¼ò½éºÍ¸ÅÊö£¨Ó¢ÎÄ£©¡±ÕÒµ½¡£

½üÆÚµÄÎÄÕ¡°MSMQ£º¿ÉÉìËõ¡¢¸ß¿ÉÓÃÐԵĸºÔØÆ½ºâ½â¾ö·½°¸£¨Ó¢ÎÄ£©¡±½éÉÜÁËÒ»ÖÖ½â¾ö·½°¸£¬ÓÃÓڸ߿ÉÓÃÐÔÏûÏ¢¶ÓÁÐ (MSMQ) µÄ¿ÉÉìËõ¸ºÔØÆ½ºâ½â¾ö·½°¸Ìåϵ½á¹¹¡£´Ë½â¾ö·½°¸ÖÐÉæ¼°ÁËÒ»ÖÖ½« Windows ·þÎñÓÃ×÷ÖÇÄÜÏûϢ·ÓÉÆ÷µÄ¿ª·¢·½°¸¡£ÕâÑùµÄ½â¾ö·½°¸ÒÔǰֻÓÐ Microsoft Visual C++® ³ÌÐòÔ±²ÅÄÜʵÏÖ£¬¶ø .NET ¿ò¼ÜµÄ³öÏָıäÁËÕâÖÖÇé¿ö¡£´ÓÏÂÃæµÄ½â¾ö·½°¸ÖУ¬Äú¿ÉÒÔ¿´µ½ÕâÒ»µã¡£

.NET ¿ò¼ÜÓ¦ÓóÌÐò

ÕâÀï½éÉܵĽâ¾ö·½°¸ÊÇÒ»ÖÖÓÃÀ´´¦ÀíÈô¸ÉÏûÏ¢¶ÓÁÐµÄ Windows ·þÎñ£»ÆäÖÐÿ¸ö¶ÓÁж¼ÊÇÓɶà¸öÏ߳̽øÐд¦Àí£¨½ÓÊպʹ¦ÀíÏûÏ¢£©¡£´¦Àí³ÌÐòʹÓÃÑ­»··¨¼¼Êõ»òÓ¦ÓóÌÐòÌØ¶¨Öµ£¨ÏûÏ¢ AppSpecific ÊôÐÔ£©´ÓÄ¿µÄ¶ÓÁÐÁбíÖзÓÉÏûÏ¢£¬²¢Ê¹ÓÃÏûÏ¢ÊôÐÔÀ´µ÷ÓÃ×é¼þ·½·¨¡££¨Ê¾Àý½ø³ÌÒ²ÊôÓÚÕâÖÖÇé¿ö¡££©ÔÚºóÒ»ÖÖÇé¿öÏ£¬×é¼þµÄÒªÇóÊÇËüÄܹ»ÊµÏÖ¸ø¶¨µÄ½Ó¿Ú IWebMessage¡£Òª´¦Àí´íÎó£¬Ó¦ÓóÌÐòÐèÒª½«²»ÄÜ´¦ÀíµÄÏûÏ¢·¢Ë͵½´íÎó¶ÓÁÐÖС£

ÏûÏ¢Ó¦ÓóÌÐòµÄ½á¹¹ÓëÒÔǰµÄ»î¶¯Ä£°å¿â (ATL) Ó¦ÓóÌÐòÏàËÆ£¬ËüÃÇÖ®¼äµÄÖ÷Òª²»Í¬ÔÚÓÚÓÃÓÚ¹ÜÀí·þÎñµÄ´úÂëµÄ·â×°ºÍ .NET ¿ò¼Ü×é¼þµÄʹÓá£Òª´´½¨ Windows ·þÎñ£¬.NET ¿ò¼ÜÓû§½ö½öÐèÒª´´½¨Ò»¸ö´Ó ServiceBase£¨À´×Ô System.ServiceControl ³ÌÐò¼¯£©¼Ì³ÐµÄÀà¡£ÕâºÁ²»Ææ¹Ö£¬ÒòΪ .NET ¿ò¼ÜÊÇÃæÏò¶ÔÏóµÄ¡£

Ó¦ÓóÌÐò½á¹¹

Ó¦ÓóÌÐòÖÐÖ÷ÒªµÄÀàÊÇ ServiceControl£¬ËüÊÇ´Ó ServiceBase ¼Ì³ÐµÄ¡£Òò¶ø£¬Ëü±ØÐëʵÏÖ OnStart ºÍ OnStop ·½·¨£¬ÒÔ¼°¿ÉÑ¡µÄ OnPause ºÍ OnContinue ·½·¨¡£ÊÂʵÉÏ£¬ÀàÊÇÔÚ¾²Ì¬·½·¨ Main ÄÚ¹¹ÔìµÄ£º

using System;

using System.ServiceProcess;

public class ServiceControl: ServiceBase

{

// ´´½¨·þÎñ¶ÔÏóµÄÖ÷Èë¿Úµã

public static void Main()

{

ServiceBase.Run(new ServiceControl());

}

// ¶¨Òå·þÎñ²ÎÊýµÄ¹¹Ôì¶ÔÏó

public ServiceControl()

{

CanPauseAndContinue = true;

ServiceName = "MSDNMessageService";

AutoLog = false;

}

protected override void OnStart(string[] args) {...}

protected override void OnStop() {...}

protected override void OnPause() {...}

protected override void OnContinue() {...}

}

ServiceControl Àà´´½¨Ò»ÏµÁÐ CWorker ¶ÔÏ󣬼´£¬ÎªÐèÒª´¦ÀíµÄÿ¸öÏûÏ¢¶ÓÁд´½¨ CWorker ÀàµÄÒ»¸öʵÀý¡£¸ù¾Ý¶¨ÒåÖд¦Àí¶ÓÁÐËùÐèµÄÏß³ÌÊýÄ¿£¬CWorker ÀàÒÀ´Î´´½¨ÁËһϵÁÐµÄ CWorkerThread ¶ÔÏó¡£CWorkerThread Àà´´½¨µÄÒ»¸ö´¦ÀíÏ߳̽«Ö´ÐÐʵ¼ÊµÄ·þÎñ¹¤×÷¡£

ʹÓà CWorker ºÍ CWorkerThread ÀàµÄÖ÷ҪĿµÄÊÇÈ·ÈÏ·þÎñ¿Ø¼þ Start¡¢Stop¡¢Pause ºÍ Continue ÃüÁî¡£ÒòΪÕâЩ½ø³Ì±ØÐëÊÇÎÞ×èÈûµÄ£¬ÃüÁî²Ù×÷×îÖÕ½«ÔÚºǫ́´¦ÀíÏß³ÌÉÏÖ´ÐС£

CWorkerThread ÊÇÒ»¸ö³éÏóÀ࣬±» CWorkerThreadAppSpecific ¡¢CWorkerThreadRoundRobin ºÍ CWorkerThreadAssembly ¼Ì³Ð¡£ÕâЩÀàÒÔ²»Í¬µÄ·½Ê½´¦ÀíÏûÏ¢¡£Ç°Á½¸öÀàͨ¹ý¸øÁíÒ»¶ÓÁз¢ËÍÏûÏ¢À´´¦ÀíÏûÏ¢£¨Æä²»Í¬Ö®´¦ÔÚÓÚÈ·¶¨½ÓÊÕ¶ÓÁз¾¶µÄ·½Ê½£©£¬×îºóÒ»¸öÀàÔòʹÓÃÏûÏ¢ÊôÐÔÀ´µ÷ÓÃ×é¼þ·½·¨¡£

.NET ¿ò¼ÜÄÚ²¿µÄ´íÎó´¦ÀíÊÇÒÔ»ùÀà Exception Ϊ»ù´¡µÄ¡£µ±ÏµÍ³Òý·¢»ò²¶»ñ´íÎóʱ£¬ÕâЩ´íÎó±ØÐëÊÇ´Ó Exception Öе¼³öµÄÀà¡£CWorkerThreadException Àà¾ÍÊÇÕâÑùÒ»ÖÖʵÏÖ£¬Ëüͨ¹ý¸½¼Ó¶îÍâÊôÐÔ£¨ÓÃÓÚ¶¨Òå·þÎñÊÇ·ñÓ¦¼ÌÐøÔËÐУ©À´À©Õ¹»ùÀà¡£

×îºó£¬Ó¦ÓóÌÐò°üº¬Á½Öֽṹ¡£ÕâЩֵÀàÐͶ¨ÒåÁ˸¨Öú½ø³Ì»òÏ̵߳ÄÔËÐÐʱ²ÎÊý£¬ÒÔ¼ò»¯ CWorker ºÍ CWorkerThread ¶ÔÏóµÄ½á¹¹¡£Ê¹ÓÃÖµÀàÐͽṹ£¨¶ø²»ÊÇÒýÓÃÀàÐÍÀࣩÄܹ»È·±£ÕâЩÔËÐÐʱ²ÎÊýά»¤µÄÊÇÊýÖµ£¨¶ø²»ÊÇÒýÓã©¡£

IWebMessage ½Ó¿Ú

CWorkerThread µÄʵÏÖÖ®Ò»ÊÇÒ»¸öµ÷ÓÃ×é¼þ·½·¨µÄÀà¡£Õâ¸öÃûΪ CWorkerThreadAssembly µÄÀàʹÓà IWebMessage ½Ó¿ÚÀ´¶¨Òå·þÎñºÍ×é¼þÖ®¼äµÄÔ¼¶¨¡£

Ó뵱ǰ°æ±¾µÄ Microsoft Visual Studio® ²»Í¬£¬C# ½Ó¿Ú¿ÉÒÔÔÚÈκÎÓïÑÔÖÐÏÔʽ¶¨Ò壬¶ø²»ÐèÒª´´½¨ºÍ±àÒë IDL Îļþ¡£C# IWebMessage ½Ó¿ÚµÄ¶¨ÒåÈçÏ£º

public interface IWebMessage

{

WebMessageReturn Process(string sMessageLabel, string sMessageBody, int iAppSpecific);

void Release();

}

ATL ´úÂëÖÐµÄ Process ·½·¨ÊÇΪ´¦ÀíÏûÏ¢¶øÖ¸¶¨µÄ¡£Process ·½·¨µÄ·µ»Ø´úÂ붨ÒåΪö¾ÙÀàÐÍ WebMessageReturn£º

public enum WebMessageReturn

{

ReturnGood,

ReturnBad,

ReturnAbort

}

ö¾ÙµÄ¶¨ÒåÈçÏ£ºGood ±íʾ¼ÌÐø´¦Àí£¬Bad ±íʾ½«ÏûϢдÈë´íÎó¶ÓÁУ¬Abort ±íʾÖÕÖ¹´¦Àí¡£Release ·½·¨Îª·þÎñÌṩÁËÇáËÉÇå³ýÀàʵÀýµÄ;¾¶¡£ÒòΪ½öÔÚÀ¬»ø»ØÊյĹý³ÌÖвŵ÷ÓÃÀàʵÀýµÄÎö¹¹º¯Êý£¬ËùÒÔÈ·±£ËùÓÐÕ¼Óðº¹ó×ÊÔ´£¨ÀýÈçÊý¾Ý¿âÁ¬½Ó£©µÄÀà¶¼ÓÐÒ»¸öÄܹ»ÔÚÎö¹¹Ö®Ç°±»µ÷Óõķ½·¨£¬ÓÃÀ´ÊÍ·ÅÕâЩ×ÊÔ´£¬ÕâÊÇÒ»Öַdz£ºÃµÄ¹¹Ë¼¡£

Ãû³Æ¿Õ¼ä

ÔÚÕâÀïÏȼòµ¥½éÉÜÒ»ÏÂÃû³Æ¿Õ¼ä¡£Ãû³Æ¿Õ¼äÔÊÐíÔÚÄÚ²¿ºÍÍⲿ±íʾÖн«Ó¦ÓóÌÐò×éÖ¯³ÉΪÂß¼­ÔªËØ¡£·þÎñÄÚµÄËùÓдúÂë¶¼°üº¬ÔÚ MSDNMessageService.Service Ãû³Æ¿Õ¼äÄÚ¡£¾¡¹Ü·þÎñ´úÂë°üº¬ÔÚÈô¸ÉÎļþÖУ¬µ«ÊÇÓÉÓÚËüÃǰüº¬ÔÚͬһÃû³Æ¿Õ¼äÖУ¬Òò´ËÓû§²»ÐèÒªÒýÓÃÆäËûÎļþ¡£

ÓÉÓÚ IWebMessage ½Ó¿Ú°üº¬ÔÚ MSDNMessageService.Interface Ãû³Æ¿Õ¼äÖУ¬Òò´ËʹÓô˽ӿڵÄÏß³ÌÀà¾ßÓÐÒ»¸ö½Ó¿ÚÃû³Æ¿Õ¼ä¡£

·þÎñÀà

Ó¦ÓóÌÐòµÄÄ¿µÄÊǼàÊӺʹ¦ÀíÏûÏ¢¶ÓÁУ¬Ã¿Ò»¶ÓÁÐÔÚÊÕµ½ÏûϢʱ¶¼Ö´Ðв»Í¬µÄ½ø³Ì¡£Ó¦ÓóÌÐòÊÇ×÷Ϊ Windows ·þÎñÀ´ÊµÏֵġ£

ServiceBase Àà

ÈçǰËùÊö£¬·þÎñµÄ»ù±¾½á¹¹ÊÇ´Ó ServiceBase ¼Ì³ÐµÄÀà¡£ÖØÒªµÄ·½·¨°üÀ¨ OnStart¡¢OnStop¡¢OnPause ºÍ OnContinue£¬Ã¿Ò»¸öÌæ´ú·½·¨¶¼ÓëÒ»¸ö·þÎñ¿ØÖƲÙ×÷Ö±½Ó¶ÔÓ¦¡£OnStart ·½·¨µÄÄ¿µÄÊÇ´´½¨ CWorker ¶ÔÏ󣬶ø CWorker ÀàÓÖ´´½¨ CWorkerThread ¶ÔÏó£¬È»ºóÔڸöÔÏóÖд´½¨Ö´ÐзþÎñ¹¤×÷µÄÏ̡߳£

·þÎñµÄÔËÐÐʱÅäÖã¨ÒÔ¼° CWorker ºÍ CWorkerThread ¶ÔÏóµÄÊôÐÔ£©ÊÇÔÚ»ùÓÚ XML µÄÅäÖÃÎļþÖÐά»¤µÄ¡£ËüµÄÃû³ÆÓë´´½¨µÄ .exe ÎļþÏàͬ£¬µ«´øÓÐÒ»¸ö .cfg ºó׺¡£ÅäÖÃʾÀýÈçÏ£º

ProcessName="Worker1"

ProcessDesc="Message Worker with 2 Threads"

ProcessType="AppSpecific"

ProcessThreads="2"

InputQueue=".\private$\test_load1"

ErrorQueue=".\private$\test_error">

ProcessName="Worker2"

ProcessDesc="Assembly Worker with 1 Thread"

ProcessType="Assembly"

ProcessThreads="1"

InputQueue=".\private$\test_load2"

ErrorQueue=".\private$\test_error">

¶Ô´ËÐÅÏ¢µÄ·ÃÎÊͨ¹ýÀ´×Ô System.Configuration ³ÌÐò¼¯µÄ ConfigManager ÀàÀ´¹ÜÀí¡£¾²Ì¬ Get ·½·¨·µ»ØÐÅÏ¢µÄ¼¯ºÏ£¬ÕâЩ¼¯ºÏ½«±»Ã¶¾ÙÒÔ»ñµÃµ¥¸öÊôÐÔ¡£ÕâЩÊôÐÔ¼¯µÄÉèÖþö¶¨Á˸¨Öú¶ÔÏóµÄÔËÐÐÊ±ÌØÕ÷¡£³ýÁËÕâÒ»ÅäÖÃÎļþ£¬Äú»¹Ó¦¸Ã´´½¨¶¨Òå XML Îļþ½á¹¹µÄͼԪÎļþ£¬²¢ÔÚÆäÖÐÒýÓÃλÓÚ·þÎñÆ÷ machine.cfg ÅäÖÃÎļþÖеÄͼԪÎļþ£º

InternalName="Process" PublicName="ProcessList"

PublicRowName="ProcessDefinition"

SchemaGeneratorFlags="EMITXMLSCHEMA">

InternalName="Output" PublicName="OutputList"

PublicRowName="OutputDefinition"

SchemaGeneratorFlags="EMITXMLSCHEMA">

PrimaryTable="Process" PrimaryColumns="ProcessName"

ForeignTable="Output" ForeignColumns="ProcessName"

MetaFlags="USECONTAINMENT"/>

ÓÉÓÚ Service Àà±ØÐëά»¤Ò»¸öÒÑ´´½¨¸¨Öú¶ÔÏóµÄÁÐ±í£¬Òò´ËʹÓÃÁË Hashtable ¼¯ºÏ£¬ÓÃÓÚ±£³ÖÀàÐͶÔÏóµÄÃû³Æ/ÊýÖµ¶ÔÁÐ±í¡£Hashtable ²»½öÖ§³Öö¾Ù£¬»¹ÔÊÐíͨ¹ý¹Ø¼ü×ÖÀ´²éѯֵ¡£ÔÚÓ¦ÓóÌÐòÖУ¬XML ½ø³ÌÃû³ÆÊÇΨһµÄ¹Ø¼ü×Ö£º

private Hashtable htWorkers = new Hashtable();

IConfigCollection cWorkers = ConfigManager.Get("ProcessList", new AppDomainSelector());

foreach (IConfigItem ciWorker in cWorkers)

{

WorkerFormatter sfWorker = new WorkerFormatter();

sfWorker.ProcessName = (string)ciWorker["ProcessName"];

sfWorker.ProcessDesc = (string)ciWorker["ProcessDesc"];

sfWorker.NumberThreads = (int)ciWorker["ProcessThreads"];

sfWorker.InputQueue = (string)ciWorker["InputQueue"];

sfWorker.ErrorQueue = (string)ciWorker["ErrorQueue"];

// ¼ÆËã²¢¶¨Òå½ø³ÌÀàÐÍ

switch ((int)ciWorker["ProcessType"])

{

case 0:

sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessRoundRobin;

break;

case 1:

sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessAppSpecific;

break;

case 2:

sfWorker.ProcessType = WorkerFormatter.SFProcessType.ProcessAssembly;

break;

default:

throw new Exception("Unknown Processing Type");

}

// Ö´Ðиü¶àµÄ¹¤×÷ÒÔ¶ÁÈ¡Êä³öÐÅÏ¢

string sProcessName = (string)ciWorker["ProcessName"];

if (htWorkers.ContainsKey(sProcessName))

throw new ArgumentException("Process Name Must be Unique: " + sProcessName);

htWorkers.Add(sProcessName, new CWorker(sfWorker));

}

ÔÚÕâ¶Î´úÂëÖÐûÓаüº¬µÄÖ÷ÒªÐÅÏ¢ÊÇÊä³öÊý¾ÝµÄ»ñÈ¡¡£Ã¿Ò»¸ö½ø³Ì¶¨ÒåÖж¼ÓÐÒ»×éÏàÓ¦µÄÊä³ö¶¨ÒåÏî¡£¸ÃÐÅÏ¢ÊÇͨ¹ýÈçϵļòµ¥²éѯ¶ÁÈ¡µÄ£º

string sQuery = "SELECT * FROM OutputList WHERE ProcessName=" +

sfWorker.ProcessName + " AND Selector=appdomain://";

ConfigQuery qQuery = new ConfigQuery(sQuery);

IConfigCollection cOutputs = ConfigManager.Get("OutputList", qQuery);

int iSize = cOutputs.Count, iLoop = 0;

sfWorker.OutputName = new string[iSize];

foreach (IConfigItem ciOutput in cOutputs)

sfWorker.OutputName[iLoop++] = (string)ciOutput["OutputName"];

CWorkerThread ºÍ Cworker Àà¶¼ÓÐÏàÓ¦µÄ·þÎñ¿ØÖÆ·½·¨£¬¸ù¾Ý·þÎñ¿ØÖƲÙ×÷½øÐе÷Óá£ÓÉÓÚ Hashtable ÖÐÒýÓÃÁËÿһ¸ö CWorker ¶ÔÏó£¬Òò´ËÐèҪö¾Ù Hashtable µÄÄÚÈÝ£¬ÒÔµ÷ÓÃÊʵ±µÄ·þÎñ¿ØÖÆ·½·¨£º

foreach (CWorker cWorker in htWorkers.Values)

cWorker.Start();

ÀàËÆµØ£¬ÊµÏÖµÄ OnPause¡¢OnContinue ºÍ OnStop ·½·¨ÊÇͨ¹ýµ÷Óà CWorker ¶ÔÏóÉϵÄÏàÓ¦·½·¨À´Ö´ÐвÙ×÷µÄ¡£

CWorker Àà

CWorker ÀàµÄÖ÷Òª¹¦ÄÜÊÇ´´½¨ºÍ¹ÜÀí CWorkerThread ¶ÔÏó¡£Start¡¢Stop¡¢Pause ºÍ Continue ·½·¨µ÷ÓÃÏàÓ¦µÄ CWorkerThread ·½·¨¡£Êµ¼ÊµÄ CWorkerThread ¶ÔÏóÊÇÔÚStart ·½·¨Öд´½¨µÄ¡£ÓëʹÓà Hashtable ¹ÜÀí¸¨Öú¶ÔÏóÒýÓÃµÄ Service ÀàÏàËÆ£¬CWorker ʹÓà ArrayList£¨¼òµ¥µÄ¶¯Ì¬Êý×飩À´Î¬»¤Ï̶߳ÔÏóµÄÁÐ±í¡£

ÔÚÕâ¸öÊý×éÄÚ²¿£¬CWorker Àà´´½¨ÁË CWorkerThread ÀàµÄÒ»¸öʵÏÖ°æ±¾¡£CWorkerThread Àࣨ½«ÔÚÏÂÃæÌÖÂÛ£©ÊÇÒ»¸ö±ØÐë¼Ì³ÐµÄ³éÏóÀà¡£µ¼³öÀඨÒåÁËÏûÏ¢µÄ´¦Àí·½Ê½£º

aThreads = new ArrayList();

for (int idx=0; idx

{

WorkerThreadFormatter wfThread = new WorkerThreadFormatter();

wfThread.ProcessName = sfWorker.ProcessName;

wfThread.ProcessDesc = sfWorker.ProcessDesc;

wfThread.ThreadNumber = idx;

wfThread.InputQueue = sfWorker.InputQueue;

wfThread.ErrorQueue = sfWorker.ErrorQueue;

wfThread.OutputName = sfWorker.OutputName;

// ¶¨Ò帨ÖúÀàÐÍ£¬²¢½«Æä²åÈ븨ÖúÏ߳̽ṹ

CWorkerThread wtBase;

switch (sfWorker.ProcessType)

{

case WorkerFormatter.SFProcessType.ProcessRoundRobin:

wtBase = new CWorkerThreadRoundRobin(this, wfThread);

break;

case WorkerFormatter.SFProcessType.ProcessAppSpecific:

wtBase = new CWorkerThreadAppSpecific(this, wfThread);

break;

case WorkerFormatter.SFProcessType.ProcessAssembly:

wtBase = new CWorkerThreadAssembly(this, wfThread);

break;

default:

throw new Exception("Unknown Processing Type");

}

// Ìí¼Ó¶ÔÊý×éµÄµ÷ÓÃ

aThreads.Insert(idx, wtBase);

}

Ò»µ©ËùÓеĶÔÏó¶¼ÒÑ´´½¨£¬¾Í¿ÉÒÔͨ¹ýµ÷ÓÃÿ¸öÏ̶߳ÔÏóµÄ Start ·½·¨À´Æô¶¯ËüÃÇ£º

foreach(CWorkerThread cThread in aThreads)

cThread.Start();

Stop¡¢Pause ºÍ Continue ·½·¨ÔÚ foreach Ñ­»·ÀïÖ´ÐеIJÙ×÷ÀàËÆ¡£Stop ·½·¨¾ßÓÐÈçϵÄÀ¬»øÊÕ¼¯²Ù×÷£º

GC.SuppressFinalize(this);

ÔÚÀàÎö¹¹º¯ÊýÖн«µ÷Óà Stop ·½·¨£¬ÕâÑù£¬ÔÚûÓÐÏÔʽµ÷Óà Stop ·½·¨µÄÇé¿öÏÂÒ²¿ÉÒÔÕýÈ·µØÖÕÖ¹¶ÔÏó¡£Èç¹ûµ÷ÓÃÁË Stop ·½·¨£¬½«²»ÐèÒªÎö¹¹º¯Êý¡£SuppressFinalize ·½·¨Äܹ»·ÀÖ¹µ÷ÓöÔÏóµÄ Finalize ·½·¨£¨Îö¹¹º¯ÊýµÄʵ¼ÊʵÏÖ£©¡£

CWorkerThread ³éÏóÀà

CWorkerThread ÊÇÒ»¸öÓÉ CWorkerThreadAppSpecifc¡¢CWorkerThreadRoundRobin ºÍ CWorkerThreadAssembly ¼Ì³ÐµÄ³éÏóÀà¡£ÎÞÂÛÈçºÎ´¦ÀíÏûÏ¢£¬¶ÓÁеĴ󲿷ִ¦ÀíÊÇÏàͬµÄ£¬ËùÒÔ CWorkerThread ÀàÌṩÁËÕâÒ»¹¦ÄÜ¡£Õâ¸öÀàÌṩÁ˳éÏó·½·¨£¨±ØÐ뱻ʵ¼Ê·½·¨Ìæ´ú£©ÒÔ¹ÜÀí×ÊÔ´ºÍ´¦ÀíÏûÏ¢¡£

ÀàµÄ¹¤×÷ÔÙÒ»´Îͨ¹ý Start¡¢Stop¡¢Pause ºÍ Continue ·½·¨À´ÊµÏÖ¡£ÔÚ Start ·½·¨ÖÐÒýÓÃÁËÊäÈëºÍ´íÎó¶ÓÁС£ÔÚ .NET ¿ò¼ÜÖУ¬ÏûÏ¢ÓÉ System.Messaging Ãû³Æ¿Õ¼ä´¦Àí£º

// ³¢ÊÔ´ò¿ª¶ÓÁУ¬²¢ÉèÖÃĬÈϵĶÁдÊôÐÔ

MessageQueue mqInput = new MessageQueue(sInputQueue);

mqInput.MessageReadPropertyFilter.Body = true;

mqInput.MessageReadPropertyFilter.AppSpecific = true;

MessageQueue mqError = new MessageQueue(sErrorQueue);

// Èç¹ûʹÓà MSMQ COM£¬Ôò½«¸ñʽ»¯³ÌÐòÉèÖÃΪ ActiveX

mqInput.Formatter = new ActiveXMessageFormatter();

mqError.Formatter = new ActiveXMessageFormatter();

Ò»µ©¶¨ÒåÁËÏûÏ¢¶ÓÁÐÒýÓ㬼´»á´´½¨Ò»¸öÏß³ÌÓÃÓÚʵ¼ÊµÄ´¦Àíº¯Êý£¨³ÆÎª ProcessMessages£©¡£ÔÚ .NET ¿ò¼ÜÖУ¬Ê¹Óà System.Threading Ãû³Æ¿Õ¼äºÜÈÝÒ×ʵÏÖÏ̴߳¦Àí£º

procMessage = new Thread(new ThreadStart(ProcessMessages));

procMessage.Start();

ProcessMessages º¯ÊýÊÇ»ùÓÚ Boolean ÖµµÄ´¦ÀíÑ­»·¡£µ±ÊýÖµÉèΪ False£¬´¦ÀíÑ­»·½«ÖÕÖ¹¡£Òò´Ë£¬Ï̶߳ÔÏóµÄ Stop ·½·¨Ö»ÉèÖÃÕâÒ» Boolean Öµ£¬È»ºó¹Ø±Õ´ò¿ªµÄÏûÏ¢¶ÓÁУ¬²¢¼ÓÈë´øÓÐÖ÷Ï̵߳ÄỊ̈߳º

// ¼ÓÈë·þÎñÏ̺߳ʹ¦ÀíÏß³Ì

bRun = false;

procMessage.Join();

// ¹Ø±Õ´ò¿ªµÄÏûÏ¢¶ÓÁÐ

mqInput.Close();

mqError.Close();

Pause ·½·¨Ö»ÉèÖÃÒ»¸ö Boolean Öµ£¬Ê¹´¦ÀíÏß³ÌÐÝÃß°ëÃëÖÓ£º

if (bPause)

Thread.Sleep(500);

×îºó£¬Ã¿Ò»¸ö Start¡¢Stop¡¢Pause ºÍ Continue ·½·¨½«µ÷ÓóéÏóµÄ OnStart¡¢OnStop¡¢OnPause ºÍ OnContinue ·½·¨¡£ÕâЩ³éÏó·½·¨ÎªÊµÏÖµÄÀàÌṩÁ˹ҹ³£¬ÒÔ²¶»ñºÍÊÍ·ÅËùÐèµÄ×ÊÔ´¡£

ProcessMessages Ñ­»·¾ßÓÐÈçÏ»ù±¾½á¹¹£º

½ÓÊÕ Message¡£

Èç¹û Message ¾ßÓгɹ¦µÄ Receive£¬Ôòµ÷ÓóéÏó ProcessMessage ·½·¨¡£

Èç¹û Receive »ò ProcessMessage ʧ°Ü£¬½« Message ·¢ËÍÖÁ´íÎó¶ÓÁÐÖС£

Message mInput;

try

{

// ´Ó¶ÓÁÐÖжÁÈ¡£¬²¢µÈºò 1 Ãë

mInput = mqInput.Receive(new TimeSpan(0,0,0,1));

}

catch (MessageQueueException mqe)

{

// ½«ÏûÏ¢ÉèÖÃΪ null

mInput = null;

// ²é¿´´íÎó´úÂ룬Á˽âÊÇ·ñ³¬Ê±

if (mqe.ErrorCode != (-1072824293) ) //0xC00E001B

{

// Èç¹ûδ³¬Ê±£¬·¢³öÒ»¸ö´íÎ󲢼Ǽ´íÎóºÅ

LogError("Error: " + mqe.Message);

throw mqe;

}

}

if (mInput != null)

{

// µÃµ½Ò»¸öÒª´¦ÀíµÄÏûÏ¢£¬µ÷Óô¦ÀíÏûÏ¢³éÏó·½·¨

try

{

ProcessMessage(mInput);

}

// ²¶»ñÒÑÖªÒ쳣״̬µÄ´íÎó

catch (CWorkerThreadException ex)

{

ProcessError(mInput, ex.Terminate);

}

// ²¶»ñδ֪Òì³££¬²¢µ÷Óà Terminate

catch

{

ProcessError(mInput, true);

}

}

ProcessError ·½·¨½«´íÎóµÄÏûÏ¢·¢ËÍÖÁ´íÎó¶ÓÁС£ÁíÍ⣬ËüÒ²¿ÉÄÜÒý·¢Òì³£À´ÖÕÖ¹Ï̡߳£Èç¹ûProcessMessage ·½·¨Òý·¢ÁËÖÕÖ¹´íÎó»ò CWorkerThreadException ÀàÐÍ£¬Ëü½«Ö´Ðд˲Ù×÷¡£

CworkerThread µ¼³öÀà

ÈÎºÎ´Ó CWorkerThread Öм̳еÄÀà¶¼±ØÐëÌṩ OnStart¡¢OnStop¡¢OnPause¡¢OnContinue ºÍ ProcessMessage ·½·¨¡£OnStart ºÍ OnStop ·½·¨»ñÈ¡²¢ÊÍ·Å´¦Àí×ÊÔ´¡£OnPause ºÍ OnContinue ·½·¨ÔÊÐíÁÙʱÊͷźÍÖØÐ»ñÈ¡ÕâЩ×ÊÔ´¡£ProcessMessage ·½·¨Ó¦¸Ã´¦ÀíÏûÏ¢£¬²¢ÔÚ³öÏÖʧ°ÜʼþʱÒý·¢ CWorkerThreadException Òì³£¡£

ÓÉÓÚ CWorkerThread ¹¹Ô캯Êý¶¨ÒåÔËÐÐʱ²ÎÊý£¬µ¼³öÀà±ØÐëµ÷ÓûùÀ๹Ô캯Êý£º

public CWorkerThreadDerived(CWorker v_cParent, WorkerThreadFormatter v_wfThread)

: base (v_cParent, v_wfThread) {}

µ¼³öÀàÌṩÁËÁ½ÖÖÀàÐ͵Ĵ¦Àí£º½«ÏûÏ¢·¢ËÍÖÁÁíÒ»¶ÓÁУ¬»òÕßµ÷ÓÃ×é¼þ·½·¨¡£½ÓÊպͷ¢ËÍÏûÏ¢µÄÁ½ÖÖʵÏÖʹÓÃÁËÑ­»·¼¼Êõ»òÓ¦ÓóÌÐòÆ«ÒÆ£¨±£ÁôÔÚÏûÏ¢ AppSpecific ÊôÐÔÖУ©£¬×÷ΪʹÓÃÄÄÒ»¶ÓÁеľö¶¨ÒòËØ¡£´Ë·½°¸ÖеÄÅäÖÃÎļþÓ¦¸Ã°üÀ¨¶ÓÁз¾¶µÄÁÐ±í¡£ÊµÏÖµÄ OnStart ºÍ OnStop ·½·¨Ó¦¸Ã´ò¿ªºÍ¹Ø±Õ¶ÔÕâЩ¶ÓÁеÄÒýÓãº

iQueues = wfThread.OutputName.Length;

mqOutput = new MessageQueue[iQueues];

for (int idx=0; idx

{

mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);

mqOutput[idx].Formatter = new ActiveXMessageFormatter();

}

ÔÚÕâЩ·½°¸ÖУ¬ÏûÏ¢µÄ´¦ÀíºÜ¼òµ¥£º½«ÏûÏ¢·¢ËͱØÒªµÄÊä³ö¶ÓÁС£ÔÚÑ­»·Çé¿öÏ£¬Õâ¸ö½ø³ÌΪ£º

try

{

mqOutput[iNextQueue].Send(v_mInput);

}

catch (Exception ex)

{

// Èç¹û´íÎóÇ¿ÖÆÖÕÖ¹Òì³£

throw new CWorkerThreadException(ex.Message, true);

}

// ¼ÆËãÏÂÒ»¸ö¶ÓÁкÅ

iNextQueue++;

iNextQueue %= iQueues;

ºóÒ»ÖÖµ÷ÓôøÏûÏ¢²ÎÊýµÄ×é¼þµÄʵÏÖ·½·¨±È½ÏÓÐȤ¡£ProcessMessage ·½·¨Ê¹Óà IWebMessage ½Ó¿Úµ÷ÈëÒ»¸ö .NET ×é¼þ¡£OnStart ºÍ OnStop ·½·¨»ñÈ¡ºÍÊÍ·Å´Ë×é¼þµÄÒýÓá£

´Ë·½°¸ÖеÄÅäÖÃÎļþÓ¦¸Ã°üº¬Á½¸öÏîÄ¿£ºÍêÕûµÄÀàÃûºÍÀàËùÔÚÎļþµÄλÖᣰ´ÕÕ IWebMessage ½Ó¿ÚÖе͍Ò壬ÔÚ×é¼þÉϵ÷Óà Process ·½·¨¡£

Òª»ñÈ¡¶ÔÏóÒýÓã¬ÐèҪʹÓà Activator.CreateInstance ·½·¨¡£´Ëº¯ÊýÐèÒªÒ»¸ö³ÌÐò¼¯ÀàÐÍ¡£ÔÚÕâÀËüÊÇ´Ó³ÌÐò¼¯Îļþ·¾¶ºÍÀàÃûÖе¼³öµÄ¡£Ò»µ©»ñÈ¡¶ÔÏóÒýÓã¬Ëü½«±»·ÅÈëºÏÊʵĽӿڣº

private IWebMessage iwmSample;

private string sFilePath, sTypeName;

// ±£´æ³ÌÐò¼¯Â·¾¶ºÍÀàÐÍÃû³Æ

sFilePath = wfThread.OutputName[0];

sTypeName = wfThread.OutputName[1];

// »ñÈ¡¶Ô±ØÒª¶ÔÏóµÄÒýÓÃ

Assembly asmSample = Assembly.LoadFrom(sFilePath);

Type typSample = asmSample.GetType(sTypeName);

object objSample = Activator.CreateInstance(typSample);

// ¶¨Ò司¶ÔÏóµÄ±ØÒª½Ó¿Ú

iwmSample = (IWebMessage)objSample;

»ñÈ¡¶ÔÏóÒýÓúó£¬ProcessMessage ·½·¨½«ÔÚ IWebMessage ½Ó¿ÚÉϵ÷Óà Process ·½·¨£º

WebMessageReturn wbrSample;

try

{

// ¶¨Òå·½·¨µ÷ÓõIJÎÊý

string sLabel = v_mInput.Label;

string sBody = (string)v_mInput.Body;

int iAppSpecific = v_mInput.AppSpecific;

// µ÷Ó÷½·¨²¢²¶×½·µ»Ø´úÂë

wbrSample = iwmSample.Process(sLabel, sBody, iAppSpecific);

}

catch (InvalidCastException ex)

{

// Èç¹ûÔÚÏûÏ¢ÄÚÈÝÖз¢Éú´íÎó£¬ÔòÇ¿ÖÆ·¢³öÒ»¸ö·ÇÖÕÖ¹Òì³£

throw new CWorkerThreadException(ex.Message, false);

}

catch (Exception ex)

{

// Èç¹û´íÎóµ÷ÓóÌÐò¼¯£¬ÔòÇ¿ÖÆ·¢³öÖÕÖ¹Òì³£

throw new CWorkerThreadException(ex.Message, true);

}

// Èç¹ûûÓдíÎó£¬Ôò¼ì²é¶ÔÏóµ÷Óõķµ»Ø×´Ì¬

switch (wbrSample)

{

case WebMessageReturn.ReturnBad:

throw new CWorkerThreadException

("Unable to process message: Message marked bad", false);

case WebMessageReturn.ReturnAbort:

throw new CWorkerThreadException

("Unable to process message: Process terminating", true);

default:

break;

}

ÌṩµÄʾÀý×é¼þ½«ÏûÏ¢ÕýÎÄдÈëÊý¾Ý¿â±í¡£Èç¹û²¶»ñµ½ÑÏÖØÊý¾Ý¿â´íÎó£¬Äú¿ÉÄÜÏ£ÍûÖÕÖ¹´¦Àí¹ý³Ì£¬µ«ÊÇÔÚÕâÀ½ö½ö½«ÏûÏ¢±ê¼ÇΪ´íÎóµÄÏûÏ¢¡£

ÓÉÓÚ´ËʾÀýÖд´½¨µÄÀàʵÀý¿ÉÄÜ»á»ñÈ¡²¢±£Áô°º¹óµÄÊý¾Ý¿â×ÊÔ´£¬ËùÒÔÓà OnPause ºÍ OnContinue ·½·¨ÊͷźÍÖØÐ»ñÈ¡¶ÔÏóÒýÓá£

¼ì²âÉ豸

¾ÍÏóÔÚËùÓÐÓÅÐãµÄÓ¦ÓóÌÐòÖÐÒ»Ñù£¬¼ì²âÉ豸ÓÃÓÚ¼à²âÓ¦ÓóÌÐòµÄ״̬¡£.NET ¿ò¼Ü´ó´ó¼ò»¯Á˽«Ê¼þÈÕÖ¾¡¢ÐÔÄܼÆÊýÆ÷ºÍ Windows ¹ÜÀí¼ì²âÉ豸 (WMI) ÄÉÈëÓ¦ÓóÌÐòµÄ¹ý³Ì¡£ÏûÏ¢Ó¦ÓóÌÐòʹÓÃʱ¼äÈÕÖ¾ºÍÐÔÄܼÆÊýÆ÷£¬¶þÕß¶¼ÊÇÀ´×Ô System.Diagnostics ³ÌÐò¼¯¡£

ÔÚ ServiceBase ÀàÖУ¬Äú¿ÉÒÔ×Ô¶¯ÆôÓÃʼþÈÕÖ¾¡£ÁíÍ⣬ServiceBase EventLog ³ÉÔ±Ö§³ÖдÈëÓ¦ÓóÌÐòʼþÈÕÖ¾£º

EventLog.WriteEntry(sMyMessage, EventLogEntryType.Information);

¶ÔÓÚдÈëʼþÈÕÖ¾¶ø²»ÊÇÓ¦ÓóÌÐòÈÕÖ¾µÄÓ¦ÓóÌÐò£¬ËüÄܹ»ºÜÈÝÒ׵ش´½¨ºÍ»ñÈ¡ EventLog ×ÊÔ´µÄÒýÓã¨ÕýÈçÔÚ CWorker ÀàÖÐËù×öµÄÒ»Ñù£©£¬²¢Äܹ»Ê¹Óà WriteEntry ·½·¨¼Ç¼ÈÕÖ¾Ï

private EventLog cLog;

string sSource = ServiceControl.ServiceControlName;

string sLog = "Application";

// ²é¿´Ô´ÊÇ·ñ´æÔÚ£¬Èç¹û²»´æÔÚ£¬Ôò´´½¨Ô´

if (!EventLog.SourceExists(sSource))

EventLog.CreateEventSource(sSource, sLog);

// ´´½¨ÈÕÖ¾¶ÔÏ󣬲¢ÒýÓÃÏÖÔÚ¶¨ÒåµÄÔ´

cLog = new EventLog();

cLog.Source = sSource;

// ÔÚÈÕÖ¾ÖÐдÈëÌõÄ¿£¬±íÃ÷´´½¨³É¹¦

cLog.WriteEntry("Òѳɹ¦´´½¨", EventLogEntryType.Information);

.NET ¿ò¼Ü´ó´ó¼ò»¯ÁËÐÔÄܼÆÊýÆ÷¡£¶ÔÓÚÿһ¸ö´¦ÀíÏ̡߳¢Ï̵߳¼³öµÄÓû§ºÍÕû¸öÓ¦ÓóÌÐò£¬ÕâÒ»ÏûÏ¢Ó¦ÓóÌÐò¶¼ÄÜÌṩ¼ÆÊýÆ÷£¬ÓÃÓÚ¸ú×ÙÏûÏ¢ÊýÁ¿ºÍÿÃëÖÓ´¦ÀíÏûÏ¢µÄÊýÁ¿¡£ÒªÌṩ´Ë¹¦ÄÜ£¬ÄúÐèÒª¶¨ÒåÐÔÄܼÆÊýÆ÷µÄÀà±ð£¬È»ºóÔö¼ÓÏàÓ¦µÄ¼ÆÊýÆ÷ʵÀý¡£

ÐÔÄܼÆÊýÆ÷µÄÀà±ðÔÚ·þÎñ OnStart ·½·¨Öж¨Òå¡£ÕâЩÀà±ð´ú±íÁ½ÖÖ¼ÆÊýÆ÷¡ª¡ªÏûÏ¢×ÜÊýºÍÿÃëÖÓ´¦ÀíµÄÏûÏ¢Êý£º

CounterCreationData[] cdMessage = new CounterCreationData[2];

cdMessage[0] = new CounterCreationData("Messages/Total", "Total Messages Processed",

PerformanceCounterType.NumberOfItems64);

cdMessage[1] = new CounterCreationData("Messages/Second", "Messages Processed a Second",

PerformanceCounterType.RateOfChangePerSecond32);

PerformanceCounterCategory.Create("MSDN Message Service", "MSDN Message Service Counters", cdMessage);

Ò»µ©¶¨ÒåÁËÐÔÄܼÆÊýÆ÷Àà±ð£¬½«´´½¨ PerformanceCounter ¶ÔÏóÒÔ·ÃÎʼÆÊýÆ÷ʵÀý¹¦ÄÜ¡£PerformanceCounter ¶ÔÏóÐèÒªÀà±ð¡¢¼ÆÊýÆ÷Ãû³ÆºÍÒ»¸ö¿ÉÑ¡µÄʵÀýÃû³Æ¡£¶ÔÓÚ¸¨Öú½ø³Ì£¬½«Ê¹ÓÃÀ´×Ô XML ÎļþµÄ½ø³ÌÃû³Æ£¬´úÂëÈçÏ£º

pcMsgTotWorker = new PerformanceCounter("MSDN Message Service", "Messages/Total", sProcessName);

pcMsgSecWorker = new PerformanceCounter("MSDN Message Service", "Messages/Second", sProcessName);

pcMsgTotWorker.RawValue = 0;

pcMsgSecWorker.RawValue = 0;

ÒªÔö¼Ó¼ÆÊýÆ÷µÄÖµ£¬½ö½öÐèÒªµ÷ÓÃÊʵ±µÄ·½·¨£º

pcMsgTotWorker.IncrementBy(1);

pcMsgSecWorker.IncrementBy(1);

×îºó˵Ã÷Ò»µã£¬·þÎñÖÕֹʱ£¬°²×°µÄÐÔÄܼÆÊýÆ÷Àà±ðÓ¦¸Ã´ÓϵͳÖÐɾ³ý£º

PerformanceCounterCategory.Delete("MSDN Message Service");

ÓÉÓÚÐÔÄܼÆÊýÆ÷ÔÚ .NET ¿ò¼ÜÖй¤×÷£¬Òò´ËÐèÒªÔËÐÐÒ»ÏîÌØÊâµÄ·þÎñ¡£´Ë·þÎñ (PerfCounterService) ÌṩÁ˹²ÏíÄÚ´æ¡£¼ÆÊýÆ÷ÐÅÏ¢½«Ð´Èë¹²ÏíÄڴ棬²¢±»ÐÔÄܼÆÊýÆ÷ϵͳ¶ÁÈ¡¡£

°²×°

ÔÚ½áÊøÒÔǰ£¬ÎÒÃÇÀ´¼òÒª½éÉÜһϰ²×°ÒÔ¼°³ÆÎª installutil.exe µÄ°²×°¹¤¾ß¡£ÓÉÓÚ´ËÓ¦ÓóÌÐòÊÇ Windows ·þÎñ£¬Ëü±ØÐëʹÓà installutil.exe À´°²×°¡£Òò´Ë£¬ÐèҪʹÓÃÒ»¸ö´Ó System.Configuration.Install ³ÌÐò¼¯ÖÐ¼Ì³ÐµÄ Installer Àࣺ

public class ServiceRegister: Installer

{

private ServiceInstaller serviceInstaller;

private ServiceProcessInstaller processInstaller;

public ServiceRegister()

{

// ´´½¨·þÎñ°²×°³ÌÐò

serviceInstaller = new ServiceInstaller();

serviceInstaller.StartType = ServiceStart.Manual;

serviceInstaller.ServiceName = ServiceControl.ServiceControlName;

serviceInstaller.DisplayName = ServiceControl.ServiceControlDesc;

Installers.Add(serviceInstaller);

// ´´½¨½ø³Ì°²×°³ÌÐò

processInstaller = new ServiceProcessInstaller();

processInstaller.RunUnderSystemAccount = true;

Installers.Add(processInstaller);

}

}

Èç´ËʾÀýÀàËùʾ£¬¶ÔÓÚÒ»¸ö Windows ·þÎñ£¬·þÎñºÍ·þÎñ½ø³Ì¸÷ÐèÒªÒ»¸ö°²×°³ÌÐò£¬ÒÔ¶¨ÒåÔËÐзþÎñµÄÕÊ»§¡£ÆäËû°²×°³ÌÐòÔÊÐí×¢²áʼþÈÕÖ¾ºÍÐÔÄܼÆÊýÆ÷µÈ×ÊÔ´¡£

×ܽá

´ÓÕâ¸ö .NET ¿ò¼ÜÓ¦ÓóÌÐòʾÀýÖпÉÒÔ¿´³ö£¬ÒÔǰֻÓÐ Visual C++ ³ÌÐòÔ±Äܹ»±àдµÄÓ¦ÓóÌÐò£¬ÏÖÔÚʹÓüòµ¥µÄÃæÏò¶ÔÏó³ÌÐò¼´¿ÉʵÏÖ¡£¾¡¹ÜÎÒÃǵÄÖØµãÊÇ C#£¬µ«±¾ÎÄËùÊöµÄÄÚÈÝҲͬÑùÊÊÓÃÓÚ Visual Basic ºÍ Managed C++¡£Ð嵀 .NET ¿ò¼Üʹ¿ª·¢ÈËÔ±Äܹ»Ê¹ÓÃÈκαà³ÌÓïÑÔÀ´´´½¨¹¦ÄÜÇ¿´ó¡¢¿ÉÉìËõµÄ Windows Ó¦ÓóÌÐòºÍ·þÎñ¡£

Ð嵀 .NET ¿ò¼Ü²»½ö¼ò»¯ºÍÀ©Õ¹Á˱à³ÌµÄÖÖÖÖ¿ÉÄÜ£¬»¹Äܹ»ÇáËɵؽ«ÈËÃǾ­³£ÒÅÍüµÄÓ¦ÓóÌÐò¼ì²âÉ豸£¨ÀýÈçÐÔÄܼà²â¼ÆÊýÆ÷ºÍʼþÈÕ־֪ͨ£©ºÏ²¢µ½Ó¦ÓóÌÐòÖС£¾¡¹ÜÕâÀïµÄÓ¦ÓóÌÐòûÓÐʹÓà Windows ¹ÜÀí¼ì²âÉ豸 (WMI)£¬µ« .NET ¿ò¼ÜͬÑùÒ²¿ÉÒÔÓ¦ÓÃËü¡£

²Î¿¼×ÊÁÏ

¿ÉÉìËõµÄ¸ß¿ÉÓÃÐÔÒµÎñ¶ÔÏó½á¹¹£¨Ó¢ÎÄ£©

MSMQ£º¿ÉÉìËõµÄ¸ß¿ÉÓÃÐÔ¸ºÔØÆ½ºâ½â¾ö·½°¸£¨Ó¢ÎÄ£©

C# ¼ò½éºÍ¸ÅÊö£¨Ó¢ÎÄ£©

C# ²Î¿¼£¨Ó¢ÎÄ£©

MSDN Online .NET ÐÅÏ¢£¨Ó¢ÎÄ£©

¹ØÓÚ×÷Õß

Carl Nolan ÔÚ±±¼ÓÀû¸£ÄáÑÇµÄ Microsoft µç×ÓÉÌÎñ½â¾ö·½°¸Ð¡×éµÄÎ÷Çø¹¤×÷¡£¸ÃС×éµÄ¹¤×÷ÖØµãÊÇʹÓà Microsoft Windows .NET ƽ̨¿ª·¢»ùÓÚ Internet µÄ½â¾ö·½°¸¡£ËûµÄµç×ÓÓʼþµØÖ·ÊÇ carlnol@microsoft.com¡£

--------------------------------------------------------------------------------

ÇëÒÔ IE4.0 ÒÔÉϰ汾 800 * 600 ä¯ÀÀ±¾Õ¾

©2001 Microsoft Corporation °æÈ¨ËùÓС£±£ÁôËùÓÐȨÀû¡£

ÔðÈα༭£ºadmin
±¾ÎÄÒýÓõØÖ·£º http://www.3pcode.com/net/2004/10/5855.htm
Ïà¹ØÎÄÕÂ