时间:2019-03-08 标签:c#disposeUserControlThread

c# dispose UserControl Thread

我有一个带有 UserControl 的 MainForm。 在我的 MainForm 中可以选择我想要显示的用户控件。每次我更改我的用户控件时,我都会处理它。

    private void buttonBar1_ItemClick(object sender, Janus.Windows.ButtonBar.ItemEventArgs e)
    {
        foreach (Control control in panelMain.Controls)
        {
            control.Dispose();                
        }
        panelMain.Controls.Clear();

        //...

        MyUserControl uc = new MyUserControl();
        MyUserControl.Dock = DockStyle.Fill;
        panelMain.Controls.Add(MyUserControl);  

        //...
    }

我的一个 UserControls 有自己的轮询线程。线程显示数据库中的一些行并每秒刷新一次。

    private Thread thread;

    public MyUserControl()
    {
        InitializeComponent();

        ThreadStart job = RefreshGui;
        thread = new Thread(job);
        thread.Start();
    }

    private void RefreshGui()
    {
        while (true)
        {
            //load Data

            Thread.Sleep(1000);
        }
    }       

现在我希望每次更改用户控件时都关闭我的线程。我已经试过了:

从未致电过:

Dispatcher.CurrentDispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
{
    thread.Abort();
}

已有相同签名的方法

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        // get rid of managed resources
    }
}

那么每次更改 UserControl 时如何停止我的线程。我不想在 MainForm 中停止我的线程!用户控件应该自己完成这项工作。

我假设这一切都与 WinForms 有关。

  1. 在处理子控件之前,您绝对应该清除控件容器。
  2. 虽然您可能可以使用 Dispose,但您也可以覆盖 OnControlRemoved,当您从容器中清除控件时将调用它。
  3. 您应该可以将 Thread.Abort() 放在 OnControlRemoved 方法中。但是,使用 Thread.Abort() 应该是最后的手段(这不像按 Ctrl-Alt-Del / End Process)。您最好检查条件,然后尽可能优雅地退出线程(建议使用 CancellationToken)。如果需要,您可以使用 Thread.Join() 来阻止 UI 线程。
  4. 您将需要使用 Invoke/BeginInvoke 从后台线程填充 UI 中的任何内容。
  5. 您应该查看 BackgroundWorker - 它专为使用 WinForms 加载线程外数据而设计。