0

このようなWindowsサービスに追加したことを除いて、これを濡らしました

public partial class TriggerHostProcesses : ServiceBase
{
    private const string MESSAGE_QUEUE = @".\Private$\Sample Queue";
    private MessageQueue _queue;
    public TriggerHostProcesses()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        SendMessage("Hope This Works");
    }

    protected override void OnStop()
    {
    }

    internal void start()
    {
        OnStart(null);
    }


    private void SendMessage(string message)
    {
        _queue = new MessageQueue(MESSAGE_QUEUE);
        Message msg = new Message();
        msg.Body = message;
        msg.Label = "Testing " + DateTime.Now.ToString();
        _queue.Send(msg,new MessageQueueTransaction());
    }
}

そしてメッセージを受け取る

 partial class HostListener : ServiceBase
{
      private const string MESSAGE_QUEUE = @".\Private$\Sample Queue";
    private MessageQueue _queue;

    public HostListener()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            var myTransaction = new MessageQueueTransaction();

            var queue = new MessageQueue(MESSAGE_QUEUE);
            var message = queue.Receive(new TimeSpan(0, 0, 20),myTransaction);
            message.Formatter = new XmlMessageFormatter(
                                new String[] { "System.String,mscorlib" });
            Console.WriteLine(message.Body.ToString());
        }
        catch(Exception ex)
        {
            Console.WriteLine("No Message");
        }
    }

    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop your service.
    }

    internal void start()
    {
        OnStart(null);
    }
}

私のメインではこれを追加しました

  var ServiceToRun1 = new TriggerHostProcesses();
        var ServiceToRun2 = new HostListener();

        if (Environment.UserInteractive)
        {
            // This used to run the service as a console (development phase only)

            ServiceToRun1.start();
            ServiceToRun2.start();

            Console.WriteLine("Press Enter to terminate ...");
            Console.ReadLine();

            ServiceToRun1.Stop();
            ServiceToRun2.Stop();
        }
        else
        {
            ServiceBase.Run(ServiceToRun1);
        }

私は例外を取得しますTimeout for the requested operation has expired.

誰かが問題が何であるかを確認できるかどうかを確認できますか?

4

2 に答える 2

2

トランザクションを正しく使用しているとは思いません。たとえば、メッセージを送信するときは、次のように使用します。

_queue.Send(msg,new MessageQueueTransaction());

ただし、これはトランザクションを開始またはコミットしません。MSDNを見ると、この例では次のコードが使用されています (私が編集):

var myTransaction = new MessageQueueTransaction();
myTransaction.Begin();
myQueue.Send("hello world", myTransaction);
myTransaction.Commit();

あなたのメッセージが送信されているとは思えないので、Receiveタイムアウトしました。

同様に、あなたの受信ロジックはトランザクションを正しく使用していないようです:

myTransaction.Begin();
var myMessage = myQueue.Receive(myTransaction); 
var body myOrder = (string)myMessage.Body;
myTransaction.Commit();

例外がRollback発生した場合にメッセージを処理して、メッセージをキューに戻すことができるようにする必要があります。

于 2013-02-10T19:28:06.483 に答える
0

これが私の最終製品です。これをWindowsサービスで使用しています。一度に 20 秒かけて、メッセージがあるかどうかを確認してから、プロセスを実行します。

public class MSMQueue:IQueue
    {

        public MSMQueue(string queueName)
        {
            Message_Queue = queueName;
        }

        public string Message_Queue { get; private set; }

        public string Pop()
        {
            MessageQueue queue = new MessageQueue(Message_Queue);

            if (queue.Transactional)
                return popTransactionalQueue(queue, new TimeSpan(0, 0, 1));
            else
                return popNormalQueue(queue, new TimeSpan(0, 0, 1));
        }

        public string Pop(TimeSpan timeSpan)
        {
            MessageQueue myQueue = new MessageQueue(Message_Queue);

            if (myQueue.Transactional)
                return popTransactionalQueue(myQueue, timeSpan);
            else
                return popNormalQueue(myQueue, timeSpan);
        }

        public void Add(string message)
        {
            // Connect to a queue on the local computer.
            MessageQueue myQueue = new MessageQueue(Message_Queue);

            // Send a message to the queue.
            if (myQueue.Transactional)
            {
                var myTransaction = new MessageQueueTransaction();
                myTransaction.Begin();
                myQueue.Send(message, myTransaction);
                myTransaction.Commit();
            }
            else
                myQueue.Send(message);
        }

        #region private methods

        private string popNormalQueue(MessageQueue queue, TimeSpan timeOut)
        {
            var message = queue.Receive(timeOut);
            message.Formatter = new XmlMessageFormatter(
                                new String[] { "System.String,mscorlib" });
            return message.Body.ToString();
        }

        private string popTransactionalQueue(MessageQueue queue, TimeSpan timeOut)
        {

            // Set the formatter.
            queue.Formatter = new XmlMessageFormatter(new Type[]
                {typeof(String)});

            // Create a transaction.
            MessageQueueTransaction myTransaction = new 
                MessageQueueTransaction();

            String message=string.Empty;

            try
            {
                myTransaction.Begin();

                Message myMessage = queue.Receive(timeOut, myTransaction); 
                message = (String)myMessage.Body;

                myTransaction.Commit();

            }

            catch (MessageQueueException e)
            {
                myTransaction.Abort();
                throw e;
            }

            return message;
        }

        #endregion
    }
于 2013-02-11T09:02:42.460 に答える