C#关于多线程与进度条


我现在知道一个方法的处理的两个端点:开始处理和处理完毕

我现在想使用线程来控制一个进度条

该方法开始处理时线程启动,处理完毕后停止线程

中间耗时由进度条来显示

由于我无法获取该方法处理所需要的时间,所以想用线程来处理

求高手指点

【提供一个实例,这是有时间来控制进度条的,仅供参考】

C#Code

delegate void RunTaskDelegate(int seconds);
        delegate void ShowProgressDelegate(int totalStep, int currentStep);

        private void ShowProgress(int totalStep, int currentStep)
        {
            progressBar1.Maximum = totalStep;
            progressBar1.Value = currentStep;
        }
        private void RunTask(int seconds)
        {
            ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress);
            for (int i = 0; i < seconds * 4; i++)
            {
                Thread.Sleep(250);
                this.Invoke(showProgress, new object[] { seconds * 4, i + 1 });
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            RunTaskDelegate runTask = new RunTaskDelegate(RunTask);
            runTask.BeginInvoke(20, null, null);
        }

C#EndCode

【在线等回复】

13 个解决方案

#1


委托与事件

#2


你用Thread.Sleep(250);来是可行的,不过UI会阻塞,可以考虑用时间差来处理。
                        DateTime dt1 = DateTime.Now; // 获取当前时间
                        DateTime dt2;
                        double diff = 0;

                        while (diff < 0.1)//间隔0.1秒则开始执行。无ui阻塞
                        {
                            dt2 = DateTime.Now;
                            TimeSpan ts = dt2.Subtract(dt1);
                            diff = (double)ts.TotalSeconds;
                            Application.DoEvents();
                        }

  方法放在下面,

#3


我是希望不适用时间来控制进度条的进度

而使用线程

希望大家再看的时候,理解我的意思

#4


引用 3 楼 gfxgza 的回复:
我是希望不适用时间来控制进度条的进度

而使用线程

希望大家再看的时候,理解我的意思

实际上你无法确切给执行代码一个进度,但你可以给出一个大概的进度。
可以将所执行的代码分成几个块,然后执行完一块后更新一次进度,更新进度的多少需要你评估每一个占总量的大致百分比。
如果块中有循环之类的代码,你也可以将其分为更小的块,每循环一次更新一次进度,这样就有更精确的进度了。
不知道楼主明白我的意思没有

#5


我就是无法获取到他执行到了哪一块啊!!!!!!!!!!!!!!11

DisableFolderBrowser(); //[开始处理]

converting.Do(coursewares, outputDirectory, startIndex); //[处理课件]

ResetDirectories(); //[处理完毕]

【开始处理】的方法是将添加文件的几个button的Enable设为不可用

【处理课件】是处理DataGridView上所有满足条件的Row,也就是说DataGridView上显示的可以是多条,但是在处理的时候不一定是全部的Row

【处理完毕】的方法是将开始禁用的button设为可用

由于我无法获取到converting.Do(coursewares, outputDirectory, startIndex);的处理过程【位于不同的层】,也即是4楼推荐我一个一个进度!

所以,我想的就是,我忽略他中间的处理过程,通过多线程抓住【开始处理】和【处理完毕】两个端点,来实现进度,但是我不是很懂多线程和progressBar1一起使用来实现我要的效果

我都发了几次帖子了,依然没有人能够解决我的问题!

头疼!我想我再说的清楚了吧!

#6


这个好处理,我做的导出Excel,多线程加完成了百分比和这个类似, 
 
总的说来,事件是不能少的,

事件的参数自己定义下,里面包括的内容,进度,对象。 


估计你是不真正垃圾,委托,事件,线程,异步调用等等。

#7


“估计你是不真正垃圾,委托,事件,线程,异步调用等等。” 中的 “垃圾” 应该是“理解” 拼音打字 lj

抱歉。

#8


(⊙o⊙)哦,没事!

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.progressbar(VS.80).aspx

这个网址提供的代码关于progressBar1,做出来的效果不是启动任务的时候就开始进度,而是完成后一并进

度,这样的话就达不到效果,LoveCSharp你试一下这个,看一下效果!!!

#9


LZ,你提供的代码已经可以用了,因为新建的线程是不能直接操作主窗口线程创建的控件的,所以需要使用代理去操作
你在线程里调用这个函数就可以了
this.Invoke(showProgress, new object[] { seconds * 4, i + 1 });
两个参数,一个进度条的最大值,一个是当前值,就调用这条函数就可以设置进度条了

#10


这样吧
this.Invoke(new ShowProgressDelegate(ShowProgress), maxvalue, value);

#11


异步调用,看需要回调

#12


感谢大家帮我解决,已经解决了!

我最终想要的效果是这样的:我添加五门课程到DataGridView上【不是从数据库读取的,而是手动添加的】

,而这五门课程可能装换的只有三门,这就的看用户想转多少门

进度条的好处是,知道他转了多少,从而达到一个提示的作用

我的最终代码我贴出来给大家看一下!!!

C#Code

【业务逻辑层】public System.Windows.Forms.ProgressBar progressBar1;

int currentValue = 1;  //[progressBar1的Value值]

[一个转换的方法里]

foreach (var c in coursewares)
            {
                //[是否需要转换]
                if (c.Istransfer == true)
                {
                    /// <summary>
                    /// 必须同时满足ppt,js,ism存在的情况下才能完成转换【可作修改】
                    /// srt可要可不要
                    /// </summary>
                    /// <param name="sender"></param>
                    /// <param name="e"></param>
                    if (c.ContainsPPT == true && c.ContainsSAJS == true && c.VideoFolder != null)
                    {
                        new CoursewareConverter().Convert(c, outputDirectory, powerPointApp, startIndex + i);
                        i++;
                    }
                }
                currentValue++;

                progressBar1.PerformStep();  [调用该方法实现++]

public int CurrentValue()  //将progressBar1的值传到View层
        {
            return currentValue;
        }

【View层】   //具体的button。实现开始转换
progressBar1.Minimum = 1;
            progressBar1.Maximum = coursewares.Count;
            progressBar1.Value = converting.CurrentValue();  //[将转换好的课件个数传给当前的progressBar1]

C#EndCode

最后的效果就是:假设添加5个,需要转换3个,那么进度条提示每转换一门,进度一个百分比!!!!

仅供参考!

#13


解决就好。
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告