首页 新闻 会员 周边 捐助

C# 关于多线程的操作

0
悬赏园豆:5 [已解决问题] 解决于 2020-07-09 10:25

主窗体是一个线程。我一进程序就创建线程A,在线程A里面创建线程B,线程A和B都需要对界面控件进行操作,目前各种报错,请问怎么完美操作线程? 

居~的主页 居~ | 初学一级 | 园豆:28
提问于:2017-09-06 11:14
< >
分享
最佳答案
0

 委托或者事件,或者直接不检查线程安全性 Control.CheckForIllegalCrossThreadCalls=false;

收获园豆:5
jqw2009 | 老鸟四级 |园豆:2341 | 2017-09-06 11:18

Control.CheckForIllegalCrossThreadCalls=false  这个已经有了,我现在的线程比较乱,线程A里面有委A-A托,委托A-A里面有线程B,线程B里面还有线程C。

居~ | 园豆:28 (初学一级) | 2017-09-06 11:22

所以现在不知道怎么统一操作。UI线程

居~ | 园豆:28 (初学一级) | 2017-09-06 11:23
其他回答(6)
0

完美的话当然是把委托交给ui线程来处理咯。

Daniel Cai | 园豆:10424 (专家六级) | 2017-09-06 11:18

UI线程就是交给主线程来处理是吧?

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-06 11:19
1 public MainWindow()
2         {
3             InitializeComponent();         
4             th = new Thread(new ThreadStart(ThreadRefresh));
5             th.SetApartmentState(ApartmentState.STA);
6             th.IsBackground = true;
7             th.Start();
8      }
 1  private void ThreadRefresh()
 2         {
 3             while (ElectronicScale)
 4             {              
 5                 Thread.Sleep(5000);
 6                 RefreshInterfaceData refreshInterfaceData = new RefreshInterfaceData(RefreshDataMethod);
 7                 IAsyncResult result = refreshInterfaceData.BeginInvoke(null, null);
 8                 while (result.IsCompleted == false)
 9                 {
10                     System.Windows.Forms.Application.DoEvents();
11                     Thread.Sleep(10);
12                 }
13                 refreshInterfaceData.EndInvoke(result);
14             }
15         }
 public bool RefreshDataMethod()
        {
            try
            {
                //加载用户列表获取
                MessageNotice();
                //待接入变化通知接口
                AccessChange();
                //系统自动接入
                SystemAutomaticAccess();
                return true;
            }
            catch (Exception ex)
            {
System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new CloseFormFunc(CloseForm));
                return false;
            }
        }

 

MessageNotice();  这个方法里面去操作控件就会出错。

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-06 11:37
0

Control.CheckForIllegalCrossThreadCalls=false;

 不推荐,游戏可以这么干。
多线程线程里面直接Control invoke就行了
花飘水流兮 | 园豆:13615 (专家六级) | 2017-09-06 11:44
0

将委托交给UI线程进行处理

fcyh | 园豆:568 (小虾三级) | 2017-09-06 11:54
0

窗体程序的话,我一般使用backgroundwork来执行后台任务,当然我用过task来执行后台任务,然后再通过委托来操作窗体,但是感觉这样没有用backgroundwork来得方便,虽然有点老旧了,不过在我看来依旧是windows窗体开发的一大利器

海之殇 | 园豆:500 (菜鸟二级) | 2017-09-06 14:06
0

一般来说后台线程是不允许访问ui线程的  所以,你如果需要对ui线程进行操作,就需要使用委托,这样就不会出现问题了

 public Form1()
        {
            InitializeComponent();
            updateText = new UpdateText(updateTextStart);
        }

        public void updateTextStart(string text)
        {
            richTextBox1.Text += text + "\r\n";
        }

        public void Form1_Load(object sender, EventArgs e)
        {
            Thread A = new Thread(StartA);
            A.Start();
        }

        public void StartA(object obj)
        {
            Thread B = new Thread(StartB);
            B.Start();
            while (true)
            {
                Thread.Sleep(1000);
                Invoke(updateText, "111111111");
            }
        }

        public void StartB(object obj)
        {
            while (true)
            {
                Thread.Sleep(1200);
                Invoke(updateText, "222222");
            }
        }

        public delegate void UpdateText(string text);
        public UpdateText updateText;
    }

高软玩家 | 园豆:217 (菜鸟二级) | 2017-09-06 15:03

如果很多控件的话这样会不会很麻烦?

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-06 17:11

使用你的这种方法,执行过程中我的界面不能动,这个是不是哪里需要优化

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-06 17:49

@久久小垠: 具体没看到  你写的东西,也不好说是哪里的问题,界面不能动,可能线程出了问题。一般使用委托,很少会出现卡死的情况,要是不行的话 你在写界面的时候 用sleep停顿几十毫秒试试

支持(0) 反对(0) 高软玩家 | 园豆:217 (菜鸟二级) | 2017-09-08 15:38
0

在线程的方法里加上参数,参数为你要操作的控件

星缘灬孤单 | 园豆:218 (菜鸟二级) | 2017-09-07 14:33

h很多控件或者一个方法里面控件需要更新多次呢

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-07 14:34

@久久小垠: 那你就写一个类,类里用多线程调用那个带一个控件参数的方法,然后这个类可以有多个控件的属性

支持(0) 反对(0) 星缘灬孤单 | 园豆:218 (菜鸟二级) | 2017-09-07 14:37

@星缘灬孤单: 有没有例子,你简单写一下语法即可

支持(0) 反对(0) 居~ | 园豆:28 (初学一级) | 2017-09-07 14:40

@久久小垠: public class A(){

public Label _label;

public Button _button;

public A(Label label1,Button button)

{

_label1=label1;_Button=button;

}

public void Methoed()

{

//处理_label,或者_button

//调用的时候把类实例化,给类里的label和button赋不同的控件,然后用线程调用这个方法

}

}

支持(0) 反对(0) 星缘灬孤单 | 园豆:218 (菜鸟二级) | 2017-09-07 14:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册