读书人

进度条用线程处理如何还是不好用啊

发布时间: 2011-12-24 23:03:24 作者: rapoo

进度条用线程处理怎么还是不好用啊?
老大们,我郁闷了,救救我啊.

using System.Threading;
private Boolean bTasking = false;
private Thread tr_Task;


public void UF_Task(Boolean bstart)
{
bTasking = bstart;
if (bstart) sBarP2.Value = 0;
if (tr_Task == null)
{
tr_Task = new Thread(new ThreadStart(UF_DoProcess));
tr_Task.IsBackground = true;
tr_Task.Name = "QBSProcess ";
tr_Task.Start();
}
if (!bstart) sBarP2.Value = 100;
}

private void UF_DoProcess()
{
try
{
MethodInvoker mip = new MethodInvoker(this.UF_ProcStep);
while (bTasking)
{
this.BeginInvoke(mip);
Thread.Sleep(100);
}
}
catch { }
}

private void UF_ProcStep()
{
if (!bTasking) return;
if (sBarP2.Value == 100) sBarP2.Value = 0;
else sBarP2.PerformStep();
}


假设我在调用一个任务A时 ,大约需要1秒,调用

UF_Task(true);
A任务;
UF_Task(false);

可是进度条没有中间状态啊,进度条只有0和100....
怎么回事啊???
在线等,老大门!!!!




[解决办法]
用timer不好么。。。
[解决办法]
只有UI线程才能操作UI控件,将对进度条value副值的操作交给UI线程来做

[解决办法]
可是进度条没有中间状态啊,进度条只有0和100....
怎么回事啊???

-----------------------

你没有在public void UF_Task(Boolean bstart)方法中去变更sBarP2.Value ,当然不会有进度条滚动的效果了。先不说你没有进度条渐进的过程,你的程序现在连进度条从0到100的过程都没有,根本不会变化。
[解决办法]
如果是.net 2.0可以使用BackgroundWorker类,它可以用于与UI线程交互
下面是一段代码,可以参考一下。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BackGroundThread
{
public partial class Form1 : Form
{
private BackgroundWorker workThread;
public Form1()
{
InitializeComponent();
workThread = new BackgroundWorker();
workThread.WorkerReportsProgress = true;
workThread.WorkerSupportsCancellation = true;

workThread.DoWork += new DoWorkEventHandler(workThread_DoWork);
workThread.ProgressChanged += new ProgressChangedEventHandler(workThread_ProgressChanged);
workThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workThread_RunWorkerCompleted);

this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
}

void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
workThread.Dispose();
}

void workThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled


// flag may not have been set, even though
// CancelAsync was called.
this.Text = "Canceled ";
}
else
{
// Finally, handle the case where the operation
// succeeded.
//resultLabel.Text = e.Result.ToString();
this.progressBar1.Value = 100;
}

}

void workThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;

}

void workThread_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;

for (int i = 0; i < 100; i++)
{
if (bw.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
System.Threading.Thread.Sleep(100);
workThread.ReportProgress(i);
}
}

}

private void button1_Click(object sender, EventArgs e)
{
workThread.RunWorkerAsync();
}

private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show( "AbC ");
}

private void button3_Click(object sender, EventArgs e)
{
workThread.CancelAsync();
}
}
}
[解决办法]
你的问题真如你所说的那样,由于用Invoke是提交给UI所在线程来完成,而UI线程此时忙于处理A任务,因此得不到及时响应。

因此你可以把这部分
UF_Task(true);
A任务;
UF_Task(false);
放到一个单独的线程去处理,这样就避免了UI线程被占用。

读书人网 >C#

热点推荐