BackgroundWorker线程没有停止winforms c#

本文关键字:winforms 线程 BackgroundWorker | 更新日期: 2023-09-27 18:18:05

我使用BackgroundWorker线程调用一个小例程,该例程在消息到达MSMQ队列时(消息每5秒到达MSMQ)从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();
    }
}

BackgroundWorker线程没有停止winforms c#

这里有两个选项:

1)在窗体的关闭事件中,调用backgroundWorker1.CancelAsync()。

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

问题是,如果你发出一个接收请求,它会阻塞后台工作线程,直到消息被接收到队列中,而CancelAsync只会请求后台工作线程被停止,它不会取消接收请求。

例如(已更新):

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

关闭表单时,是否终止worker?如果没有,如果有对表单或工作器的引用(事件处理程序?),那么它将不会获得GCd并停留在周围。在打开第二个实例时,您可能会有两个后台工作程序运行....