c#dispose UserControl Thread

时间:2015-05-06 10:06:38

标签: c# multithreading user-controls dispose

我有一个带有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);  

        //...
    }

On我的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);
        }
    }       

现在我想在每次更改usercontrol时关闭我的线程。我已经尝试过了:

从未打电话:

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中停止我的主题! usercontrol应该自行完成这项工作。

1 个答案:

答案 0 :(得分:2)

我假设这完全是WinForms。

  1. 在处置子控件之前,您一定要清除Controls容器。
  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加载线程数据而设计的。