gpt4 book ai didi

c# - BackgroundWorker 线程没有停止 winforms c#

转载 作者:太空宇宙 更新时间:2023-11-03 14:08:37 24 4
gpt4 key购买 nike

我正在使用 BackgroundWorker 线程调用一个小例程,该例程在消息到达 MSMQ 队列时立即从 MSMQ 接收消息(消息每 5 秒到达一次 msmq)它到达我的应用程序这是使用 BackgroundWorker 线程。下面是我的 Win Form 类。我是线程的新手,所以如果我做错了什么请道歉

问题:我的应用程序是 MDI 应用程序,当我第一次执行我的应用程序时,它工作得很好,并且一旦它进入队列就会收到 MSMQ 消息,这是每 5 秒一次,但是每当我关闭这个表单时是一个子窗体,它关闭得很好,但在打开同一个窗体后,我收到了来自 MSMQ 的消息,有 10 秒的延迟,所以这意味着我在后台工作线程中搞砸了一些东西,我试图取消这个后台工作线程但是我失败了,无法正确取消或终止线程。请帮助并分享您的经验。下面是我的表单代码。

public partial class FrmBooking : BookingManager.Core.BaseForm.BaseForm
{
internal const string queName = @"messageServer\private$\Response";
private Int32 counter = 0;
BackgroundWorker backgroundWorker1 = new BackgroundWorker();


public FrmBooking()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged+=new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.DoWork+=new DoWorkEventHandler(backgroundWorker1_DoWork);

}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgWorker = sender as BackgroundWorker;

if (bgWorker.CancellationPending)
{
e.Cancel = true;
return;
}


try
{

MessageQueue messageQueue = null;
if (MessageQueue.Exists(queName))
{
messageQueue = new MessageQueue(queName);
}
else
{
MessageQueue.Create(queName);
}

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

System.Messaging.Message msg = messageQueue.Receive();



bgWorker.ReportProgress(100, msg);

}
catch (Exception ex) { }


}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled)
{
backgroundWorker1.RunWorkerAsync();
}


}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

System.Messaging.Message msg = e.UserState as System.Messaging.Message;

listBoxControl1.Items.Add(msg.Body.ToString());
counter++;
labelControl1.Text = String.Format("Total messages received {0}", counter.ToString());
}

private void FrmBooking_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();

}
}

最佳答案

这里有两个选择:

1) 在Form的Closing事件中,调用backgroundWorker1。 CancelAsync ().

2) 更好的方法是完全删除后台工作程序并为此使用 MessageQueue 的 native 异步处理机制。您可以使用 BeginReceive 启动队列请求添加 ReceivedCompleted 事件处理程序后的方法,然后在完成的事件处理程序中,处理消息并重新启动请求。

问题是,如果您发出 Receive 请求,它将阻塞后台工作线程,直到队列中收到一条消息,而 CancelAsync 只会请求停止后台工作线程,它不会取消 Receive 请求.

例如(更新):

public partial class FrmBooking : BookingManager.Core.BaseForm.BaseForm
{
public FrmBooking()
{
InitializeComponent();

this.FormClosing += new FormClosingEventHandler(FrmBooking_FormClosing);
}

internal const string queName = @"messageServer\private$\Response";
private Int32 counter = 0;
private MessageQueue messageQueue = null;

private bool formIsClosed = false;

private void FrmBooking_Load(object sender, EventArgs e)
{
StartQueue();
}

void FrmBooking_FormClosing(object sender, FormClosingEventArgs e)
{
// Set the flag to indicate the form is closed
formIsClosed = true;

// If the messagequeue exists, close it
if (messageQueue != null)
{
messageQueue.Close();
}
}

private void StartQueue()
{
if (MessageQueue.Exists(queName))
{
messageQueue = new MessageQueue(queName);
}
else
{
MessageQueue.Create(queName);
}

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

// Add an event handler for the ReceiveCompleted event.
messageQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MessageReceived);

messageQueue.BeginReceive(TimeSpan.FromSeconds(15));
}

// Provides an event handler for the ReceiveCompleted event.
private void MessageReceived(Object source, ReceiveCompletedEventArgs asyncResult)
{
if (!this.formIsClosed)
{
// End the asynchronous receive operation.
System.Messaging.Message msg = messageQueue.EndReceive(asyncResult.AsyncResult);

// Display the message information on the screen.
listBoxControl1.Items.Add(msg.Body.ToString());
counter++;
labelControl1.Text = String.Format("Total messages received {0}", counter.ToString());

// Start receiving the next message
messageQueue.BeginReceive(TimeSpan.FromSeconds(15));
}
}

}

关于c# - BackgroundWorker 线程没有停止 winforms c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8549050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com