Проблема с фоновым рабочим потоком - PullRequest
1 голос
/ 31 января 2011

Я использую фоновый работник в своем приложении

мой код для этого

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

в чем проблема с фоновым рабочим, мой класс очереди выглядит так

 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 ]

1 голос
/ 31 января 2011

Можете ли вы уточнить контекст вашего приложения?

Это приложение Windows Forms?Консольное приложение?Или WPF?

Это может иметь какое-то отношение к квартирному состоянию потока.Потоки, используемые BackgroundWorker, по умолчанию имеют значение MTA (и вы не можете переопределить его).В то время как потоки, созданные вручную, могут иметь в квартирах значение STA.

0 голосов
/ 31 января 2011

Я не уверен, что ваш подход верен. Я читал сообщения одно за другим и связывал соответствующие события.

По ссылке:

Цикл сообщений

Последняя строка в приведенном выше примере была "queue.BeginReceive ()".Это критическая линия для успешного внедрения очереди сообщений Microsoft, поскольку она предоставляет средства для непрерывного прослушивания очереди сообщений.При каждом получении сообщения процесс прослушивания останавливается.Это помогает обеспечить потокобезопасную среду.Однако это также означает, что разработчик обязан возобновить прослушивание очереди.

Использование очереди сообщений Microsoft MSMQ и C #

Также в последнем битекода, который у вас есть в вашем вопросе:

if (allMessages.Length > 0)
        {

            msg = messageQueue.Receive();

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


            return readMessage;
        }
        else
        {
            return null;
        }

Это позволит получить все сообщения и использовать их, но вернет только первое сообщение, даже если в очереди их больше одного.

...