C#多线程打开窗口

sevenxiyi 2018-01-24 06:45:43
Vs2013中load事件,绘制表格及图表的函数费时,createMainCol(),createDetailCol()等等,导致打开窗口极慢。现在想法是通过线程委托执行这几个函数。怎么实现?有可执行代码不
...全文
1083 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevenxiyi 2018-06-08
  • 打赏
  • 举报
回复
public BackgroundWorker bkBar = new BackgroundWorker();//委托显示进度条 private BackgroundWorker bkDB = new BackgroundWorker();//添加委托,更新统计数据及产量统计图、饼图 bkBar.WorkerReportsProgress = true; bkBar.WorkerSupportsCancellation = true; bkBar.DoWork += new DoWorkEventHandler(DoWork); bkBar.ProgressChanged += new ProgressChangedEventHandler(ProgressChanged); bkBar.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWork); bkDB.DoWork += new DoWorkEventHandler(DoWorkDB);//添加委托,更新统计数据及产量统计图、饼图 bkDB.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWorkDB); public void DoWork(object sender, DoWorkEventArgs e) { // 事件处理,指定处理函数 e.Result = ProcessProgress(bkBar, e); } public void ProgressChanged(object sender, ProgressChangedEventArgs e) { // bkBar.ReportProgress 会调用到这里,此处可以进行自定义报告方式 notifyForm.SetNotifyInfo(e.ProgressPercentage, "处理进度:" + Convert.ToString(e.ProgressPercentage) + "%"); } public void CompleteWork(object sender, RunWorkerCompletedEventArgs e) { if (bkDBResult == 1 && bkCapacityResult == 1) { notifyForm.Close(); } //MessageBox.Show("处理完毕!"); } private int ProcessProgress(object sender, DoWorkEventArgs e) { for (int i = 0; i <= 100; i++) { if (bkBar.CancellationPending) { e.Cancel = true; return -1; } else { // 状态报告 bkBar.ReportProgress(i); // 等待,用于UI刷新界面,很重要 System.Threading.Thread.Sleep(10); } } return -1; } load 事件: bkBar.RunWorkerAsync(this); ======我试着这样,效果还可以,不知道做得怎么样?
Roselle_2013 2018-02-06
  • 打赏
  • 举报
回复
可以试试将方法改成异步。这样绘制是异步完成的,不影响用户其他操作。 关于.net 4.0 下无法使用async 和await 可以nuget一个包Microsoft.bcl.Async即可。

private async void Form_Loaded(object sender, RoutedEventArgs e)
        {
            await System.Threading.Tasks.Task.Factory.StartNew(new Action(createMainCol));
            //其他UI操作
        }
king422212809 2018-02-06
  • 打赏
  • 举报
回复
用BackgroundWorker,然后在load的时候启动worker执行。这样试试。
蘋果虫 2018-01-25
  • 打赏
  • 举报
回复
Thread t= new Thread(new ThreadStart(()=> { //要运行的方法 })); t.Start()
zhuowp 2018-01-25
  • 打赏
  • 举报
回复
按照我的理解,这是没法通过多线程解决的。在Windows窗口程序中,所有关于ui绘制的操作都必须放到ui线程中执行。即便你用多线程,最后也会调用this.Invoke或者Dispatche.Invoke,把左右的绘制操作扔回UI线程去执行。 解决思路可以通过部分加载表格,看看有没有用。
  • 打赏
  • 举报
回复
要注意操作控件的代码必须放到 Control.BeginInvoke/Invoke 委托中注册执行。并不是简单地“通过线程委托执行这几个函数”就完了。
exception92 2018-01-25
  • 打赏
  • 举报
回复
通过异步加载数据方式,让你的加载窗口动作分为两个,第一个是窗口加载不需要等待数据返回才显示出来,第二个通过async/await 关键字标识一个加载数据方法。也就是窗口先加载出来,数据同时填充进来但不影响窗口继续显示,这时候你可以加上一个进度条之类的提示。Task.Run 线程操作控件时注意避免跨线程操作错误。
zhuowp 2018-01-25
  • 打赏
  • 举报
回复
引用 7 楼 sevenxiyi 的回复:
[quote=引用 1 楼 From_TaiWan 的回复:]

using System.Threading.Tasks;
//.............

protected void Form1_Load(object sender, EventArgs e)
{
    Task t1 = Task.Run(new Action(createMainCol));
    Task t2.Task.Run(new Action(createDetailCol));

    //do other things

}

编译不过,报错:System.Threading.Tasks.Task”并不包含“Run”的定义[/quote] System.Threading.Tasks.Task.Factory.StartNew(action); Task可以这样用。 不过我觉得异步对ui操作用处不大。 我能想到的解决方法就是别一下子全部绘制。可以多放几个类似Tab页的东西,在每个页面点击后绘制。
sevenxiyi 2018-01-25
  • 打赏
  • 举报
回复
引用 1 楼 From_TaiWan 的回复:

using System.Threading.Tasks;
//.............

protected void Form1_Load(object sender, EventArgs e)
{
    Task t1 = Task.Run(new Action(createMainCol));
    Task t2.Task.Run(new Action(createDetailCol));

    //do other things

}

编译不过,报错:System.Threading.Tasks.Task”并不包含“Run”的定义
秋的红果实 2018-01-24
  • 打赏
  • 举报
回复

Task t2=Task.Run(new Action(createDetailCol));
秋的红果实 2018-01-24
  • 打赏
  • 举报
回复

using System.Threading.Tasks;
//.............

protected void Form1_Load(object sender, EventArgs e)
{
    Task t1 = Task.Run(new Action(createMainCol));
    Task t2.Task.Run(new Action(createDetailCol));

    //do other things

}

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧