线程Control.Invoke [英] Thread Control.Invoke

查看:741
本文介绍了线程Control.Invoke的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数

public void ShowAllFly()
{  
        cbFly.Items.Clear();
        cbFly.Items.Add("Uçuş Seçiniz...");

        dsFlyTableAdapters.tblFlyTableAdapter _t=new KTHY.dsFlyTableAdapters.tblFlyTableAdapter();
        dsFly _mds = new dsFly();
        _mds.EnforceConstraints = false;
        dsFly.tblFlyDataTable _m = _mds.tblFly;
        _t.Fill(_m);
        foreach (DataRow _row in _m.Rows)
        {
            cbFly.Items.Add(_row["FlyID"].ToString()+"-"+_row["FlyName"].ToString() + "-" + _row["FlyDirection"].ToString() + "-" + _row["FlyDateTime"].ToString());
        }
        _Thread.Abort();
        timer1.Enabled = false;
        WaitPanel.Visible = false;
}

在功能的Form_Load本一样;

In Form_Load Function Like this;

{
    _Thread = new System.Threading.Thread(new System.Threading.ThreadStart(ShowAllFly));
    _Thread.Start();
    _Thread.Priority = System.Threading.ThreadPriority.Normal;
}

但是当我运行它;

But When I run it;

在ShowAllFly功能

in ShowAllFly function

cbFly.Items.Clear(); ----  HERE Gives ERROR  LIKE  Control.Invoke must be used to interact with controls created on a separate thread.

这是什么问题?

推荐答案

有螺纹的两个黄金规则Windows窗体:

There are two golden rules of threading in Windows Forms:


  • 请不要触摸任何控件属性或方法从任何线程比它创建控件的处理的另外一个(不是明确列出作为是好等)(通常有只有一个UI线程)

  • 请不要阻塞UI线程任何时间的长短显著,否则你就会使应用程序无法响应

为了与来自不同的线程的UI交互,你需要马歇尔的号召到UI线程,使用委托并调用 Control.Invoke / 的BeginInvoke 。您的可以的测试,你是否需要调用调用使用 InvokeRequired 属性,但这几天我个人倾向于只是做也无妨 - 没有太多的处罚调用,当你不需要

In order to interact with the UI from a different thread, you need to "marshall" the call to the UI thread, using a delegate and calling Control.Invoke/BeginInvoke. You can test whether or not you need to call Invoke using the InvokeRequired property, but these days I personally tend to just do it anyway - there's not much penalty for invoking when you don't need to.

在C#3拉姆达前pressions(或C#匿名方法2)使这个有很多更舒适为好。

Lambda expressions in C# 3 (or anonymous methods in C# 2) make this a lot more pleasant as well.

例如,你可以使用:

cbFly.Invoke((MethodInvoker)(() => cbFly.Items.Clear()));

所有括号碍事了一下,所以你可能要添加一个扩展方法就是这样,如果你使用C#3:

All the brackets get in the way a bit, so you might want to add an extension method like this, if you're using C# 3:

public static void Invoke(this Control control, MethodInvoker action)
{
    control.Invoke(action);
}

然后,你可以这样做:

Then you could do:

cbFly.Invoke(() => cbFly.Items.Clear());

这是一个很好的协议更简单。通常你可以逃脱使用 MethodInvoker 通过捕捉你需要委托内访问的任何变量。

which is a good deal simpler. Usually you can get away with using a MethodInvoker by capturing any variables you need to access within the delegate.

请参阅我穿线教程或的乔阿尔巴哈利的了解更多详情。

See my threading tutorial or Joe Albahari's for more details.

作为一个次要的事情,我看你使用 Thread.Abort的 - 其实你自己的线程,尽管有后,其他调用它。为什么?中止任何线程的其他的比你自己是一个突发事件只有呼叫类型(这通常应遵循的程序正在反正卸载),我看不到任何理由中止当前线程时,有仍有许多工作之后做...

As a secondary matter, I see you're using Thread.Abort - in fact on your own thread, despite it having other calls after it. Why? Aborting any thread other than your own is an "emergencies only" type call (which should usually be followed by the app being unloaded anyway) and I can't see any reason to abort the current thread when there's still work to be done afterwards...

这篇关于线程Control.Invoke的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆