c#桌面编程combobox导致子线程变慢
今天遇到一个奇葩情况,c#的桌面编程,有一个动作,获取combobox的值传递给子线程,子线程在开子进程调用外部exe并同步输出
只要把combobox的值往里面传递,子线程的执行效率就会大幅降低
不传递使用combobox的值时,子线程执行用时2s左右,传递并使用combobox后,用时20s接近30
奇葩,本人不会c#,猜测是不是引用传递到子线程的时候,引起了不必要的更新?
有没有大佬知道是个什么情况?
感激不尽! 看情况应该是从子线程里直接取了combobox的值。
你可以从主线程里取值再传递给子线程。这样就好了。 C#子线程和控件交互,最好用委托或事件。 goldli 发表于 2019-8-12 14:27
看情况应该是从子线程里直接取了combobox的值。
你可以从主线程里取值再传递给子线程。这样就好了。
{:1_924:}有这个怀疑
其实取值就是在主线程完成的,拼接别的字符串后传递给子线程的
因为自己并不会c#,所以不太清楚,字符串拼接,是值传递还是引用传递?
测试了把传进去的clone之后仍然影响效率
感觉这个时候应该已经是值传递了,有点迷 wtujoxk 发表于 2019-8-12 14:39
C#子线程和控件交互,最好用委托或事件。
子线程用了委托和界面进行交互,仍然不行
屏蔽子线程内部所有和界面交互的代码,效率依然受影响
相当于子线程现在完全是独立的和外部无交互的状态,唯一可能存在的就是combobox的值被引用传递进来了,但是也只有获取动作,没有别的动作。
就感觉这个问题很奇葩,
在主线程获取combobox的值,拼接后传给进子线程,和不传给子线程,完全是两个效率 井右寺 发表于 2019-8-12 14:51
子线程用了委托和界面进行交互,仍然不行
屏蔽子线程内部所有和界面交互的代码,效率依然受影响
相当于 ...
上代码或者工程! wtujoxk 发表于 2019-8-12 15:10
上代码或者工程!
嗯,因为是客户代码,所以不太方便,截取部分做伪代码吧
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(), "提示");
}
}
}
}
wtujoxk 发表于 2019-8-12 15:10
上代码或者工程!
{:1_887:}我也不太清楚正确性,麻烦大佬帮忙看看,可能存在的问题点
计时是callexe执行前后的时间差
之前试过,把取值放到selectchange里面赋值给外部变量,然后通过这个变量进行拼接,没效果
把callexe里面和外部交互的代码屏蔽,没有效果
就有点懵 本帖最后由 wtujoxk 于 2019-8-12 16:18 编辑
略改了一下,你自己测试看看!
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;
}
} new Thread(delegate(){ CallExe(command); }).Start();
改成用Task.Factory.StartNew(......)
页:
[1]