G
Guest
Hi.
The problem is a bit hard to explain.
I have a ServicedComponent method which runs a distributed transaction
consisting on a a MessageQueue reception and several database operations.
That ServicedComponent method is called from a pool of threads which get
blocked in the Receive method of the queue. At that moment there are as many
open transactions in the DTC as the number of threads in the pool. After 60
seconds of inactivity the transactions get cancelled by the DTC and the
threads get unblocked and everything starts again. My question is, how can I
achieve that a thread calls the ServicedComponent method (and thus starts a
new transaction) only when there is a message on the queue to be received?.
The problem is I get a lot of cancelled transactions because of timeouts of
the DTC, as I need a distributed transaction i cannot use the BeginReceive
method. If I use the BeginPeek method and instance the ServicedComponent on
the PeekCompleted, all the threads get unblocked and the same problem arises
again. Can anybody help me?
this is my code:
class Worker {
private int threadId;
public Worker (int threadId) {
this.threadId=threadId;
}
//doWork is the ThreadStart method
public void doWork() {
//ShippingProcess.endShippingProcess is a static bool field
while (!ShippingProcess.endShippingProcess) {
try {
using (MessageHandler mh = new MessageHandler()) {
mh.handleMessage();
}
}
catch (Exception e) {
//Write EventLogEntry
}
}
}
}
[Transaction(TransactionOption.Required)]
public class MessageHandler : ServicedComponent {
public MessageHandler() {
}
[AutoComplete()]
public void handleMessage() {
SHQM shippingMessage;
STQM stockMessage;
using (MessageQueue queue = new MessageQueue(SHIPPING_QUEUE_STRING)) {
try {
Type[] shipMessageType = {typeof(SHQM)};
queue.Formatter = new XmlMessageFormatter(shipMessageType);
//ALL THE THREADS GET BLOCKED HERE
shippingMessage =
(SHQM)queue.Receive(MessageQueueTransactionType.Automatic).Body;
}
catch (MessageQueueException e) {
//Write EventLog
throw;
}
catch (Exception e) {
//Write EventLog
throw;
}
}
//DB operatios go here
}
}
}
Regards, Rodrigo.
The problem is a bit hard to explain.
I have a ServicedComponent method which runs a distributed transaction
consisting on a a MessageQueue reception and several database operations.
That ServicedComponent method is called from a pool of threads which get
blocked in the Receive method of the queue. At that moment there are as many
open transactions in the DTC as the number of threads in the pool. After 60
seconds of inactivity the transactions get cancelled by the DTC and the
threads get unblocked and everything starts again. My question is, how can I
achieve that a thread calls the ServicedComponent method (and thus starts a
new transaction) only when there is a message on the queue to be received?.
The problem is I get a lot of cancelled transactions because of timeouts of
the DTC, as I need a distributed transaction i cannot use the BeginReceive
method. If I use the BeginPeek method and instance the ServicedComponent on
the PeekCompleted, all the threads get unblocked and the same problem arises
again. Can anybody help me?
this is my code:
class Worker {
private int threadId;
public Worker (int threadId) {
this.threadId=threadId;
}
//doWork is the ThreadStart method
public void doWork() {
//ShippingProcess.endShippingProcess is a static bool field
while (!ShippingProcess.endShippingProcess) {
try {
using (MessageHandler mh = new MessageHandler()) {
mh.handleMessage();
}
}
catch (Exception e) {
//Write EventLogEntry
}
}
}
}
[Transaction(TransactionOption.Required)]
public class MessageHandler : ServicedComponent {
public MessageHandler() {
}
[AutoComplete()]
public void handleMessage() {
SHQM shippingMessage;
STQM stockMessage;
using (MessageQueue queue = new MessageQueue(SHIPPING_QUEUE_STRING)) {
try {
Type[] shipMessageType = {typeof(SHQM)};
queue.Formatter = new XmlMessageFormatter(shipMessageType);
//ALL THE THREADS GET BLOCKED HERE
shippingMessage =
(SHQM)queue.Receive(MessageQueueTransactionType.Automatic).Body;
}
catch (MessageQueueException e) {
//Write EventLog
throw;
}
catch (Exception e) {
//Write EventLog
throw;
}
}
//DB operatios go here
}
}
}
Regards, Rodrigo.