2011-01-31 3 views
1

Я использую фон рабочего в моей заявкефона Проблема Worker Thread

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

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

Избавьтесь от этого ловушечного пустого блока catch, чтобы вы могли диагностировать проблему. Поместите трассировку стека исключения, если это не поможет. –

+0

Какова проблема, с которой вы столкнулись. – CodingBarfield

+0

, когда я вызываю метод из фонового рабочего public MsmqMessageFormat ReadMessageFromMSMQ (string queueName), этот метод не называется – viky

ответ

1

Можете ли вы уточнить контекст своей заявки?

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

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

+0

На самом деле это приложение multiLayeer, процесс backgrounworker находится в моей библиотеке классов, и я добавляю эту ссылку в библиотеку классов в своем консольном приложении и вызываю этот процесс с консоли application – viky

+0

Это не так, поток MTA в обоих случаях. –

+0

извините, я не могу это получить – viky

0

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

Из ссылке:

The Message Loop

В последней строке в приведенном выше примере был "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; 
     } 

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

Смежные вопросы