1

I am using background worker in my Application

my code for this

 void CreateThreadForEachServer()
 {
    DataAccess oDA = new DataAccess();

    List<Server> allServerData = oDA.GetAllServers();

    foreach (Server serverData in allServerData)
    {
        backgroundWorker = new BackgroundWorker();

        backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

        backgroundWorker.RunWorkerAsync(serverData);

    }
}

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    Server server = (Server)e.Argument;
    CreateSnapshotForEachServer(server);
}

void CreateSnapshotForEachServer(Server server)
{
    DataAccess oDA = new DataAccess();
    MsmqMessageFormat message = new MsmqMessageFormat();

    try
    {
        message = new Queue().ReadMessageFromMSMQ(server.ServerName);
    }
    catch
    {
    }
 }

My problem is when I am calling this method

 try
 {
     message = new Queue().ReadMessageFromMSMQ(server.ServerName);
 }
 catch
 {
 }

in a background worker then i can not able to call this method just read a message from MSMQ

But when i can't use background worker just call this method in simple thread like this

void CreateThreadForEachServer()
{
    DataAccess oDA = new DataAccess();

    List<Server> allServerData = oDA.GetAllServers();

    foreach (Server serverData in allServerData)
    {
        ThreadStart t = delegate { CreateSnapshotForEachServer(serverData); };
        Thread td = new Thread(t);                
        td.Priority = ThreadPriority.Highest;
        td.Start();
    }
}

then this method call properly

try
{
    message = new Queue().ReadMessageFromMSMQ(server.ServerName);
}
catch
{
}

what is the problem with background worker my Queue class is like this

 class Queue
 {
     public MsmqMessageFormat ReadMessageFromMSMQ(string queueName)
     {
         MessageQueue messageQueue = null;

         messageQueue = new MessageQueue(@".\Private$\" + queueName);

         messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(MsmqMessageFormat) });

         System.Messaging.Message msg = null;
         System.Messaging.Message[] allMessages = messageQueue.GetAllMessages();

         if (allMessages.Length > 0)
         {
             msg = messageQueue.Receive();

             MsmqMessageFormat readMessage = (MsmqMessageFormat)(msg.Body);

             return readMessage;
         }
         else
         {
             return null;
         }
     }
 }

and MsmqMessageFormat class is like this

[Serializable]
public class MsmqMessageFormat
{      
    public Zvol Zvol { get; set;}
    public List<PolicyInterval> listPolicyIntervalInfo = new List<PolicyInterval>(); 
}
Andrew Bezzub
  • 15,744
  • 7
  • 51
  • 73
viky
  • 11
  • 2

2 Answers2

1

Can you clarify on the context of your application?

Is it a Windows Forms app? Console app? Or WPF?

It could have something to do with the apartmentstate of the thread. Threads used by the BackgroundWorker are defaulted to MTA (and you can't override it). While threads created manually could have there apartmentstate set to STA.

TheNameless
  • 363
  • 3
  • 8
  • Actually it is multiLayeer application the backgrounworker process is in my classlibrary and i add this class library reference in my console application and call this process from console application – viky Jan 31 '11 at 13:32
0

I'm not sure about your approach is correct.. I would read messages one by one and bind the appropriate events.

From the link:

The Message Loop

The final line in the example above was "queue.BeginReceive()". This is a critical line to a successful implementation of Microsoft Message Queue in that it provides the means for continuous listening on the message queue. Each time a message is received, the listening process stops. This helps provide a thread-safe environment. However, it also means it's the developer's responsibility to resume listening to the queue.

Using the Microsoft Message Queue MSMQ and C#

Also in the last bit of code you have in your question:

if (allMessages.Length > 0)
        {

            msg = messageQueue.Receive();

            MsmqMessageFormat readMessage = (MsmqMessageFormat)(msg.Body);


            return readMessage;
        }
        else
        {
            return null;
        }

This will get all messages and consume them, but will only return the first message even if there are more than one in the queue.

StefanE
  • 7,578
  • 10
  • 48
  • 75