public void Acknowledge() { if (_committed) { return; } _committed = true; _txn?.Commit(); _txn?.Dispose(); }
/// <summary> /// Message must be provided, Sends a given msg /// </summary> /// <param name="qMsg"></param> /// <param name="w"> </param> public static void SendQMsg(ref System.Messaging.MessageQueue qMsg, ref System.Messaging.Message w) { System.Messaging.MessageQueueTransaction mqt = new System.Messaging.MessageQueueTransaction(); mqt.Begin(); qMsg.Send(w, mqt); mqt.Commit(); mqt.Dispose(); mqt = null; w.Dispose(); w = null; }
public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken) { string jobId = null; MessageQueueTransaction transaction; var queueIndex = 0; do { cancellationToken.ThrowIfCancellationRequested(); queueIndex = (queueIndex + 1) % queues.Length; var queueName = queues[queueIndex]; transaction = new MessageQueueTransaction(); using (var messageQueue = GetMessageQueue(queueName)) { try { transaction.Begin(); var message = queueIndex == 0 ? messageQueue.Receive(SyncReceiveTimeout, transaction) : messageQueue.Receive(new TimeSpan(1), transaction); message.Formatter = _formatter.Value; jobId = (string)message.Body; } catch (MessageQueueException ex) { transaction.Abort(); transaction.Dispose(); if (ex.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout) { throw; } } } } while (jobId == null); return new MsmqFetchedJob(transaction, jobId); }
static void Main(string[] args) { string path = @"kim-msi\private$\kimqueue2"; MessageQueue queue = null; if (!MessageQueue.Exists(path)) { queue = MessageQueue.Create(path, true); } else queue = new MessageQueue(path); //queue.Purge(); //return; // queue.ReceiveCompleted += Queue_ReceiveCompleted;//非同步寫法BeginReceive接收Send事件 // queue.BeginReceive(); var messages = queue.GetAllMessages(); for (int i = 0; i < 10; i++) { if (messages.Count() == 0) { Message message = new Message(i.ToString()); queue.Send(message, MessageQueueTransactionType.Single); } else { MessageQueueTransaction tran = new MessageQueueTransaction(); tran.Begin(); var msg = queue.Receive(tran); if (msg == null) break; System.Messaging.XmlMessageFormatter stringFormatter; stringFormatter = new System.Messaging.XmlMessageFormatter( new string[] { "System.String" }); msg.Formatter = stringFormatter; Console.WriteLine(" e.Message:" + msg.Body); if (i % 2 == 0) tran.Dispose(); else tran.Commit(); } } Console.ReadLine(); }
public void Send(object message) { var transaction = new MessageQueueTransaction(); try { transaction.Begin(); _messageQueue.Send(message, transaction); transaction.Commit(); } catch { transaction.Abort(); throw; } finally { transaction.Dispose(); } }
private void OnMessagePeeked(object sender, PeekCompletedEventArgs e) { var transaction = new MessageQueueTransaction(); try { transaction.Begin(); var message = _messageQueue.Receive(transaction); MessageReceived(this, new MessageReceivedEventArgs(message)); } catch { transaction.Abort(); throw; } finally { transaction.Dispose(); } }
MSMQ.Message Receive(MSMQ.MessageQueueTransaction txn) { try { _queue.MessageReadPropertyFilter = Filters.Read; // read full details return(RecieveCore(txn)); } catch (MSMQ.MessageQueueException ex) when(ex.MessageQueueErrorCode == MSMQ.MessageQueueErrorCode.IOTimeout) { // we have already peeked to see if a message is available, but another thread or process may have already read the message from the queue, hence the timeout return(null); } catch (MSMQ.MessageQueueException ex) when(ex.MessageQueueErrorCode == MSMQ.MessageQueueErrorCode.TransactionUsage) { // we attempted a transactions receive on a non-transactional queue _isTransactional = false; txn.Dispose(); return(Receive(null)); // recurse without transaction } }
/// <summary> /// Received the next available transport message from the input queue via MSMQ. Will create a new <see cref="MessageQueueTransaction"/> and stash /// it under the <see cref="CurrentTransactionKey"/> key in the given <paramref name="context"/>. If one already exists, an exception will be thrown /// (because we should never have to receive multiple messages in the same transaction) /// </summary> public async Task<TransportMessage> Receive(ITransactionContext context) { if (context == null) throw new ArgumentNullException("context"); if (_inputQueueName == null) { throw new InvalidOperationException("This MSMQ transport does not have an input queue, hence it is not possible to reveive anything"); } var queue = GetInputQueue(); if (context.Items.ContainsKey(CurrentTransactionKey)) { throw new InvalidOperationException("Tried to receive with an already existing MSMQ queue transaction - while that is possible, it's an indication that something is wrong!"); } var messageQueueTransaction = new MessageQueueTransaction(); messageQueueTransaction.Begin(); context.OnCommitted(async () => messageQueueTransaction.Commit()); context.OnDisposed(() => messageQueueTransaction.Dispose()); context.Items[CurrentTransactionKey] = messageQueueTransaction; try { var message = queue.Receive(TimeSpan.FromSeconds(1), messageQueueTransaction); if (message == null) { messageQueueTransaction.Abort(); return null; } var headers = _extensionSerializer.Deserialize(message.Extension, message.Id); var body = new byte[message.BodyStream.Length]; await message.BodyStream.ReadAsync(body, 0, body.Length); return new TransportMessage(headers, body); } catch (MessageQueueException exception) { if (exception.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { return null; } if (exception.MessageQueueErrorCode == MessageQueueErrorCode.InvalidHandle) { _log.Info("Queue handle for '{0}' was invalid - will try to reinitialize the queue", _inputQueueName); ReinitializeInputQueue(); } if (exception.MessageQueueErrorCode == MessageQueueErrorCode.QueueDeleted) { _log.Warn("Queue '{0}' was deleted - will not receive any more messages", _inputQueueName); return null; } throw new IOException( string.Format("Could not receive next message from MSMQ queue '{0}'", _inputQueueName), exception); } }
/// <summary> /// Runs a single job thread /// </summary> /// <param name="data"></param> private void RunFrameworkJob(Message queueMessage, MessageQueueTransaction transaction) { JobTimer jobTimer = new JobTimer(processorJob.MaxRunTimeMilliseconds, Thread.CurrentThread); // The timer terminates jobs that take too much time to run try { int retryJobTimes = 0; IWorkflowMessage workflowMessage = queueMessage.Body as IWorkflowMessage; bool isCheckDepends = true; if (workflowMessage.JobID < 0) // This is a re-run { workflowMessage.JobID = -workflowMessage.JobID; isCheckDepends = false; } executor.RunFrameworkJob(workflowMessage, retryJobTimes, isCheckDepends); retryJobTimes = 0; } catch (Exception e) { new WorkflowException("Error running framework job", e); } finally { pool.Release(); jobTimer.StopTimer(); Interlocked.Decrement(ref JobsRunning); // Commit removing of the queue message at the end of the job try { if (transaction != null) { transaction.Commit(); transaction.Dispose(); } } catch (InvalidOperationException e) { new WorkflowException("Error commiting queue transaction: The transaction you are trying to commit has not started.", e); } catch (MessageQueueException e) { new WorkflowException("Error commiting queue transaction: An internal Message Queuing error occured.", e); } } //Find out the active Queue for the next Job LoadActiveQueue(); }
/// <summary> /// Sends a message to a message queue. /// </summary> /// <param name="target"></param> /// <param name="message"></param> private void SendMessage(MessageQueue target, Message message) { if (target.Transactional && target.Path.IndexOf("\\private$\\") != -1) { MessageQueueTransaction tran = new MessageQueueTransaction(); try { tran.Begin(); target.Send(message, tran); tran.Commit(); } catch { tran.Abort(); } finally { tran.Dispose(); } } else target.Send(message); }
public void KillRemoteProcessMSG(string computerName, string pcID) { var path = "FormatName:Direct=OS:" + computerName.ToLower() + "\\private$\\requestdeletequeue"; MessageQueue rmTmsq = new MessageQueue(path); System.Messaging.Message msg = new System.Messaging.Message("Shutdown message, the purpose is to shutdown a process on a remote PC"); MessageQueueTransaction trans = new MessageQueueTransaction(); try { trans.Begin(); rmTmsq.Send(msg, pcID, trans); trans.Commit(); } catch (Exception e) { throw e; } finally { trans.Dispose(); } }
// Overloaded method used to store the threads ID and what file gets opened when CustomRun is ran. public void RunCmd(string target, string fileName, LabClient client) { var pID = ""; using (var process = new Process()) { process.StartInfo.FileName = target; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardInput = true; var output = new StringBuilder(); var error = new StringBuilder(); using (var outputWaitHandle = new AutoResetEvent(false)) using (var errorWaitHandle = new AutoResetEvent(false)) { process.OutputDataReceived += (sender, e) => { if (e.Data == null) { outputWaitHandle.Set(); } }; process.ErrorDataReceived += (sender, e) => { if (e.Data == null) { errorWaitHandle.Set(); } else { if (e.Data.Contains("ID")) { var index = e.Data.IndexOf("ID"); var temp = e.Data.Substring(index, e.Data.Length - index - 1); pID = temp.Substring(3, temp.Length - 3); var cp1 = new CompAndProcesses(); cp1.computer = client; cp1.processName = fileName; cp1.threadID = pID; CompAndProcesseses.Add(cp1); //Send a message to LabClients, if LabClients puts a respond message in the replyqueue. var path = "FormatName:Direct=OS:" + client.ComputerName.ToLower() + "\\private$\\requestqueue"; MessageQueue rmTmsq = new MessageQueue(path); System.Messaging.Message msg = new System.Messaging.Message("The purpose is to check whenever a process has been started"); MessageQueueTransaction trans = new MessageQueueTransaction(); try { trans.Begin(); rmTmsq.Send(msg, pID, trans); trans.Commit(); } catch (Exception ee) { throw ee; } finally { trans.Dispose(); } } error.AppendLine(e.Data); } }; try { process.Start(); } catch (Exception e) { } process.BeginOutputReadLine(); process.BeginErrorReadLine(); var timeout = 15000; if (process.WaitForExit(timeout) && outputWaitHandle.WaitOne(timeout) && errorWaitHandle.WaitOne(timeout)) { //Could type some Process.Exist code here but it aint needed. Debug.Write(output); Debug.Write("ERROR:" + error); } } } }
/// <summary> /// Add a job for the framework to process /// </summary> /// <param name="jobName">The name of the job in the framework's workflow file</param> /// <param name="message">A class containing the message data</param> public static void AddFrameworkJob(string jobName, IWorkflowMessage message) { // Add a message to the Queue ProcessorJob processorJob = new ProcessorJob() { JobName = jobName, CreatedDate = DateTime.Now }; WorkflowConfiguration.LoadFrameworkConfig(processorJob); ProcessorQueue processorQueue = GetActiveQueue(processorJob, QueueOperationType.Delivery); MessageQueue workflowQueue = new MessageQueue(processorQueue.MessageQueue); MessageQueueTransaction transaction = new MessageQueueTransaction(); try { if (processorQueue.MessageQueueType == MessageQueueType.Transactional) { transaction.Begin(); workflowQueue.Send(message, jobName, transaction); transaction.Commit(); } else { workflowQueue.Send(message, jobName); } } catch (Exception e) { if (processorQueue.MessageQueueType == MessageQueueType.Transactional && transaction.Status == MessageQueueTransactionStatus.Pending) transaction.Abort(); throw new WorkflowException("Error adding message to Queue", e); } finally { transaction.Dispose(); workflowQueue.Dispose(); } }
// Missing fragments are marked as rejected in a separate transaction and are sent to sender's DLQ on commit. private void PerformHouseKeeping(string correlationId) { string subQueueName = Utilities.GetSubQueueName(correlationId); string subQueuePath = "FormatName:DIRECT=OS:" + this.queue.MachineName + @"\" + this.queue.QueueName + ";" + subQueueName; MessageQueue subQueue = new MessageQueue(subQueuePath); Message messageToReject = null; // MarkMessageRejected works only with transaction MessageQueueTransaction rejectTransaction = new MessageQueueTransaction(); rejectTransaction.Begin(); // ReceiveById to clear the first header fragment whose Id is put in all other fragment's correlation id // This is in a separate try-catch so that it proceeds with marking other fragments in case first fragment // is the one that is lost try { messageToReject = subQueue.ReceiveById(correlationId, rejectTransaction); NativeMethods.MarkMessageRejected(subQueue.FormatName, messageToReject.LookupId); } catch (MessageQueueException) { // Don't do anything } catch (InvalidOperationException) { // Don't do anything } // Marks other fragments in subqueue as rejected try { while (true) { messageToReject = subQueue.ReceiveByCorrelationId(correlationId, rejectTransaction); NativeMethods.MarkMessageRejected(subQueue.FormatName, messageToReject.LookupId); } } catch (MessageQueueException) { // Don't do anything and just come out of the loop } catch (InvalidOperationException) { // Don't do anything and just come out of the loop } // Safe reject in case message becomes available in main queue try { messageToReject = this.queue.ReceiveById(correlationId, rejectTransaction); NativeMethods.MarkMessageRejected(subQueue.FormatName, messageToReject.LookupId); } catch (MessageQueueException) { // Don't do anything } catch (InvalidOperationException) { // Don't do anything } // Mark other fragments in main queue as rejected try { while (true) { messageToReject = this.queue.ReceiveByCorrelationId(correlationId, rejectTransaction); NativeMethods.MarkMessageRejected(this.queue.FormatName, messageToReject.LookupId); } } catch (MessageQueueException) { // Don't do anything and just come out of the loop } catch (InvalidOperationException) { // Don't do anything and just come out of the loop } finally { subQueue.Dispose(); subQueue.Close(); rejectTransaction.Commit(); rejectTransaction.Dispose(); } }
// Main method that performs the receive operation // If normal message, returns message to application // If large message, performs reassembly and return message to application // This method throws LargeMessageQueueException and delete fragments if holes are found private Message ReceiveGeneric(string correlationId, TimeSpan timeout, MessageQueueTransaction transaction, MessageQueueTransactionType transactionType) { MessageQueueTransaction internalTransaction = transaction; bool transactionFlag = (internalTransaction != null) ? true : false; MessageQueueTransaction deleteTransaction = null; // Holds the initial state of the filter value. this is done so that this filter // is reverted back to its initial state (initial = when it entered the API) bool receiveFilterCorrelationId = this.queue.MessageReadPropertyFilter.CorrelationId; bool receiveFilterAppSpecific = this.queue.MessageReadPropertyFilter.AppSpecific; bool receiveFilterBody = this.queue.MessageReadPropertyFilter.Body; bool receiveFilterLookupId = this.queue.MessageReadPropertyFilter.LookupId; this.queue.MessageReadPropertyFilter.CorrelationId = true; this.queue.MessageReadPropertyFilter.AppSpecific = true; this.queue.MessageReadPropertyFilter.Body = true; this.queue.MessageReadPropertyFilter.LookupId = true; try { // Creates an internal transaction if there was no transaction from the application if (!transactionFlag) { internalTransaction = new MessageQueueTransaction(); internalTransaction.Begin(); } // Holds the message Id of first fragment string largeSequenceId = string.Empty; LargeMessageProperties largeMessageProperties = null; MessageQueue subQueue = null; // The overall send formatting is BinaryMessageFormatter, so the receive should also be that IMessageFormatter formatter = new BinaryMessageFormatter(); int checkPeekMessageStatus = (int)Parameters.ReceiveAction.Restart; int statusMessageAppSpecific = (int)Parameters.ReceiveAction.None; do { // First gets the status message from the status queue, reference the sub-queue using the // identifier in status message, perform corresponding receive/reject operation this.stream = new MemoryStream(); bool lookForStatusMessage = true; Message statusMessage = null; while (lookForStatusMessage) { try { // API firsts peeks from status queue and then receives/deletes the status message. // This is done to clear junk status messages that may have come to occupy the status queue statusMessage = this.PeekFromStatusQueue(correlationId); statusMessage.Formatter = formatter; statusMessageAppSpecific = statusMessage.AppSpecific; largeSequenceId = (string)statusMessage.Body; if (statusMessageAppSpecific == (int)Parameters.ReceiveAction.Delete) { try { deleteTransaction = new MessageQueueTransaction(); deleteTransaction.Begin(); statusMessage = this.ReceiveFromStatusQueue(statusMessage.LookupId, deleteTransaction, MessageQueueTransactionType.None, false); statusMessage.Formatter = formatter; throw new LargeMessageQueueException(largeSequenceId, "Fragments missing"); } catch (InvalidOperationException) { deleteTransaction.Abort(); deleteTransaction.Dispose(); lookForStatusMessage = true; } } else { checkPeekMessageStatus = (int)Parameters.ReceiveAction.None; } try { subQueue = this.GetSubQueue(largeSequenceId); // throws exception if subqueue empty this.message = subQueue.PeekByLookupId(MessageLookupAction.Last, 0); this.message.Formatter = formatter; try { statusMessage = this.ReceiveFromStatusQueue(statusMessage.LookupId, internalTransaction, transactionType, false); statusMessage.Formatter = formatter; lookForStatusMessage = false; } catch (InvalidOperationException) { lookForStatusMessage = true; } } catch (InvalidOperationException) { // Comes here when GetSubQueue throws exception. Just do a descructive receive and start status queue peek again // this exception occurs when status queue contains junk data (status message for nonexistent subqueue) try { statusMessage = this.ReceiveFromStatusQueue(statusMessage.LookupId, internalTransaction, transactionType, true); statusMessage.Formatter = formatter; } catch (InvalidOperationException) { // The status message to be received destructively has not been removed from queue. Don't do anything } lookForStatusMessage = true; } } catch (InvalidOperationException) { lookForStatusMessage = false; if (correlationId == null) { try { this.GetNextMessageSequenceInQueue(this.queue, largeSequenceId); } catch (InvalidOperationException) { // Empty main queue this.message = this.queue.Peek(timeout); this.message.Formatter = formatter; } } else { // If correlationId does not exist in queue, throw it to application this.PeekFromMsmq(correlationId, timeout, this.queue.CreateCursor(), PeekAction.Current); } this.message.Formatter = formatter; // If normal message, return single message to application if (this.message.CorrelationId == Utilities.GetEmptyCorrelationIdStr()) { this.ReceiveFromMsmq(this.queue, this.message.LookupId, internalTransaction, transactionType); return this.message; } if (this.message.AppSpecific == Parameters.HEADER_FRAGMENT_ID) { largeSequenceId = this.message.Id; } else { largeSequenceId = this.message.CorrelationId; } subQueue = this.GetSubQueue(largeSequenceId); } checkPeekMessageStatus = (int)Parameters.ReceiveAction.None; } while ((checkPeekMessageStatus != (int)Parameters.ReceiveAction.Complete) && (checkPeekMessageStatus != (int)Parameters.ReceiveAction.Restart)) { if (statusMessageAppSpecific == (int)Parameters.ReceiveAction.Complete) { checkPeekMessageStatus = (int)Parameters.ReceiveAction.Complete; } else { checkPeekMessageStatus = this.CheckReceiveMessage(subQueue, correlationId, largeSequenceId); } if (checkPeekMessageStatus == (int)Parameters.ReceiveAction.Complete) { if (statusMessageAppSpecific == (int)Parameters.ReceiveAction.None) { statusMessageAppSpecific = (int)Parameters.ReceiveAction.Complete; this.SendToStatusQueue(correlationId, statusMessageAppSpecific, largeSequenceId); checkPeekMessageStatus = (int)Parameters.ReceiveAction.Restart; } else if (statusMessageAppSpecific == (int)Parameters.ReceiveAction.Complete) { try { while (true) { this.message = this.ReceiveFromMsmq(subQueue, TimeSpan.Zero, internalTransaction, transactionType); this.message.Formatter = formatter; // First fragment has the control values if (this.message.AppSpecific == Parameters.HEADER_FRAGMENT_ID) { largeSequenceId = this.message.Id; } else if (this.message.AppSpecific == Parameters.TRAILER_FRAGMENT_ID) { largeMessageProperties = this.GetLargeMessageHeader(this.message); // All message fragments assembled this.PrepareLargeMessage(largeMessageProperties); if (!transactionFlag) { internalTransaction.Commit(); } return this.message; } else { this.AssembleFragments(); } } } finally { } } else if (statusMessageAppSpecific == (int)Parameters.ReceiveAction.Delete) { throw new LargeMessageQueueException(largeSequenceId, "Fragments missing"); } } else if (checkPeekMessageStatus == (int)Parameters.ReceiveAction.Pending) { try { this.message = this.queue.PeekByCorrelationId(largeSequenceId, timeout); this.message.Formatter = formatter; } catch (InvalidOperationException) { // This exception is thrown if more messages available in queue but not with largeSequenceId // Checking again because the exception could be because another application may // have moved the successive fragment to subqueue if (!this.CheckCompleteMessage(subQueue)) { throw new LargeMessageQueueException(largeSequenceId, "Fragment after " + this.message.AppSpecific + " missing"); } else { // look for another large message sequence checkPeekMessageStatus = (int)Parameters.ReceiveAction.Restart; } } catch (MessageQueueException) { // This exception is thrown if no messages available in queue // Checking again because the exception could be because another application may // have moved the successive fragment to subqueue if (!this.CheckCompleteMessage(subQueue)) { throw new LargeMessageQueueException(largeSequenceId, "Fragment after " + this.message.AppSpecific + " missing"); } else { // look for another large message sequence checkPeekMessageStatus = (int)Parameters.ReceiveAction.Restart; } } } } this.stream.Close(); } while (checkPeekMessageStatus == (int)Parameters.ReceiveAction.Restart); return null; } catch (LargeMessageQueueException lqe) { if (!string.IsNullOrEmpty(lqe.CorrelationId)) { this.PerformHouseKeeping(lqe.CorrelationId); if (deleteTransaction != null) { deleteTransaction.Commit(); deleteTransaction.Dispose(); } } if (!transactionFlag) { internalTransaction.Abort(); } throw; } catch (Exception) { if (!transactionFlag) { internalTransaction.Abort(); } if (deleteTransaction != null) { deleteTransaction.Abort(); deleteTransaction.Dispose(); } throw; } finally { if (this.stream != null) { this.stream.Close(); } this.queue.MessageReadPropertyFilter.CorrelationId = receiveFilterCorrelationId; this.queue.MessageReadPropertyFilter.AppSpecific = receiveFilterAppSpecific; this.queue.MessageReadPropertyFilter.LookupId = receiveFilterLookupId; this.queue.MessageReadPropertyFilter.Body = receiveFilterBody; } }
public static void SendMessage(string message, MessageQueue msgQueue) { MessageQueue msgLocal = msgQueue; System.Messaging.Message msg = new System.Messaging.Message(message); MessageQueueTransaction transaction = new MessageQueueTransaction(); try { transaction.Begin(); msgLocal.Send(msg, Environment.MachineName, transaction); transaction.Commit(); } catch (System.Exception e) { // cancel the transaction. transaction.Abort(); // propagate the exception. throw e; } finally { // dispose of the transaction object. transaction.Dispose(); } }