后台工作线程问题

发布于 2024-10-15 00:17:01 字数 2661 浏览 2 评论 0原文

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

我的代码

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幻梦 2024-10-22 00:17:01

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

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

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

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.

满天都是小星星 2024-10-22 00:17:01

我不确定你的方法是否正确。我会一一阅读消息并绑定适当的事件。

从链接:

消息循环

上例中的最后一行
是“queue.BeginReceive()”。这是一个
成功的关键线
微软消息的实现
队列因为它提供了手段
用于连续收听
消息队列。每次有一条消息
收到后,监听过程停止。
这有助于提供线程安全的
环境。然而,这也意味着
开发商有责任
恢复监听队列。

使用 Microsoft 消息队列 MSMQ 和 C#

同样在您的文件中的最后一段代码中问题:

if (allMessages.Length > 0)
        {

            msg = messageQueue.Receive();

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


            return readMessage;
        }
        else
        {
            return null;
        }

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文