背景工人线程问题

时间:2011-01-31 12:51:11

标签: c# multithreading backgroundworker

我在我的应用程序中使用后台工作程序

我的代码

 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
    {
    }
 }

我的问题是当我调用此方法时

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

在后台工作程序中,然后我无法调用此方法只读取来自MSMQ的消息

但是当我不能使用后台工作者时,只需在这样的简单线程中调用此方法

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();
    }
}

然后这个方法正确调用

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

后台工作者的问题是我的Queue类是这样的

 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;
         }
     }
 }

和MsmqMessageFormat类就是这样的

[Serializable]
public class MsmqMessageFormat
{      
    public Zvol Zvol { get; set;}
    public List<PolicyInterval> listPolicyIntervalInfo = new List<PolicyInterval>(); 
}

2 个答案:

答案 0 :(得分:1)

您能澄清一下申请的背景吗?

它是Windows Forms应用程序吗?控制台应用?还是WPF?

它可能与线程的公寓状态有关。 BackgroundWorker使用的线程默认为MTA(您无法覆盖它)。手动创建的线程可以将公寓状态设置为STA。

答案 1 :(得分:0)

我不确定你的方法是否正确..我会逐一阅读消息并绑定相应的事件。

从链接:

  

消息循环

     

上例中的最后一行   是“queue.BeginReceive()”。这是一个   成功的关键路线   Microsoft Message的实现   排队因为它提供了手段   持续听取   消息队列。每次消息都是   收到后,听取过程停止了。   这有助于提供线程安全   环境。但是,它也意味着   这是开发人员的责任   继续听队列。

Using the Microsoft Message Queue MSMQ and C#

同样在你问题的最后一段代码中:

if (allMessages.Length > 0)
        {

            msg = messageQueue.Receive();

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


            return readMessage;
        }
        else
        {
            return null;
        }

这将获取所有消息并使用它们,但即使队列中有多个消息,它也只会返回第一条消息。