吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1638|回复: 9
收起左侧

[求助] c#桌面编程combobox导致子线程变慢

[复制链接]
井右寺 发表于 2019-8-12 13:43
今天遇到一个奇葩情况,
c#的桌面编程,有一个动作,获取combobox的值传递给子线程,子线程在开子进程调用外部exe并同步输出
只要把combobox的值往里面传递,子线程的执行效率就会大幅降低
不传递使用combobox的值时,子线程执行用时2s左右,传递并使用combobox后,用时20s接近30
奇葩,本人不会c#,猜测是不是引用传递到子线程的时候,引起了不必要的更新?
有没有大佬知道是个什么情况?
感激不尽!

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

goldli 发表于 2019-8-12 14:27
看情况应该是从子线程里直接取了combobox的值。
你可以从主线程里取值再传递给子线程。这样就好了。
wtujoxk 发表于 2019-8-12 14:39
 楼主| 井右寺 发表于 2019-8-12 14:45
goldli 发表于 2019-8-12 14:27
看情况应该是从子线程里直接取了combobox的值。
你可以从主线程里取值再传递给子线程。这样就好了。

有这个怀疑
其实取值就是在主线程完成的,拼接别的字符串后传递给子线程的
因为自己并不会c#,所以不太清楚,字符串拼接,是值传递还是引用传递?
测试了把传进去的clone之后仍然影响效率
感觉这个时候应该已经是值传递了,有点迷
 楼主| 井右寺 发表于 2019-8-12 14:51
wtujoxk 发表于 2019-8-12 14:39
C#子线程和控件交互,最好用委托或事件。

子线程用了委托和界面进行交互,仍然不行
屏蔽子线程内部所有和界面交互的代码,效率依然受影响
相当于子线程现在完全是独立的和外部无交互的状态,唯一可能存在的就是combobox的值被引用传递进来了,但是也只有获取动作,没有别的动作。
就感觉这个问题很奇葩,
在主线程获取combobox的值,拼接后传给进子线程,和不传给子线程,完全是两个效率
wtujoxk 发表于 2019-8-12 15:10
井右寺 发表于 2019-8-12 14:51
子线程用了委托和界面进行交互,仍然不行
屏蔽子线程内部所有和界面交互的代码,效率依然受影响
相当于 ...

上代码或者工程!
 楼主| 井右寺 发表于 2019-8-12 15:36
wtujoxk 发表于 2019-8-12 15:10
上代码或者工程!

嗯,因为是客户代码,所以不太方便,截取部分做伪代码吧
[C#] 纯文本查看 复制代码
    public partial class Form1 : Form
    {
        public delegate void UpdateUI();
        UpdateUI updateUI;

        private void button1_Click(object sender, EventArgs e)
        {
            string command = cbx.SelectedItem.ToString() + " " + tbx4.Text.Trim();
            StartCMD1(command);
            updateUI = delegate
            {
                tbx4.Text = "";

            };
            tbx4.Invoke(updateUI);
            tbx4.Focus();
        }
        public void StartCMD1(string command)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(CallExe));
            thread.Start(command);//开始线程 
        }
        public void CallExe(object command)
        {
            Process p = new Process();
            try
            {
                //command
                //要执行进程的名称
                p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\client\\" + "homekit_download_client.exe";
                p.StartInfo.Arguments = command.ToString();
                // MessageBox.Show(command.ToString());
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory + "\\client";
                //可能接受來自調用程序的輸入信息
                p.StartInfo.RedirectStandardInput = true;
                //由調用程序獲取輸出信息
                p.StartInfo.RedirectStandardOutput = true;
                //不顯示程序窗口
                p.StartInfo.CreateNoWindow = true;

                p.Start();//啟動程序

                p.StandardInput.AutoFlush = true;

                //获取CMD窗口的輸出信息:
                string sOutput = p.StandardOutput.ReadToEnd();
                updateUI = delegate
                {
                    tbx2.Text = sOutput + "\r\n";
                };
                tbx2.Invoke(updateUI);
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "提示");
            }
        }

    }
}

 楼主| 井右寺 发表于 2019-8-12 15:41
wtujoxk 发表于 2019-8-12 15:10
上代码或者工程!

我也不太清楚正确性,麻烦大佬帮忙看看,可能存在的问题点
计时是callexe执行前后的时间差
之前试过,把取值放到selectchange里面赋值给外部变量,然后通过这个变量进行拼接,没效果
把callexe里面和外部交互的代码屏蔽,没有效果
就有点懵
wtujoxk 发表于 2019-8-12 16:17
本帖最后由 wtujoxk 于 2019-8-12 16:18 编辑

略改了一下,你自己测试看看!
[C#] 纯文本查看 复制代码
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            string command = cbx.SelectedItem.ToString() + " " + tbx4.Text.Trim();

            new Thread(delegate(){ CallExe(command); }).Start();

            UpdateUI(tbx4, "");
            tbx4.Focus();
        }
        public void CallExe(object command)
        {
            Process p = new Process();
            try
            {
                //command
                //要执行进程的名称
                p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\client\\" + "homekit_download_client.exe";
                p.StartInfo.Arguments = command.ToString();
                // MessageBox.Show(command.ToString());
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.WorkingDirectory = System.Environment.CurrentDirectory + "\\client";
                //可能接受來自調用程序的輸入信息
                p.StartInfo.RedirectStandardInput = true;
                //由調用程序獲取輸出信息
                p.StartInfo.RedirectStandardOutput = true;
                //不顯示程序窗口
                p.StartInfo.CreateNoWindow = true;

                p.Start();//啟動程序

                p.StandardInput.AutoFlush = true;

                //获取CMD窗口的輸出信息:
                string sOutput = p.StandardOutput.ReadToEnd();

                UpdateUI(tbx2, sOutput + Environment.NewLine);

                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "提示");
            }
        }
        private void UpdateUI(Control c, string content)
        {
            if (c.InvokeRequired)
                c.Invoke((EventHandler)delegate { c.Text = content; });
            else
                c.Text = content;
        }
    }
goldli 发表于 2019-8-13 15:42
new Thread(delegate(){ CallExe(command); }).Start();
改成用Task.Factory.StartNew(......)
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-27 02:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表