【发布时间】:2016-09-27 19:59:59
【问题描述】:
我创建了一个 Windows 窗体程序,它分解文件并将其组件发送到服务器。这些文件很大,所以我创建了一个progressBar,这样用户就不会认为它在交易发生时冻结了。我想做的是有一些机制,只有当所有线程都完成而不阻塞 UI 线程时才会主动触发(同样,所以人们不会认为它被冻结了)。我能想到的最好的办法是一种被动的“等到真的”,但我觉得必须有更好的方法来做到这一点。我已经尝试过尝试创建一个事件或回调,但老实说,我最终比开始时更加困惑。这是我现在如何执行此操作的示例:
public partial class Program : Form
{
private readonly OpenFileDialog _ofd = new OpenFileDialog();
public delegate void BarDelegate();
private string _path;
private void button1_Click(object sender, EventArgs e)
{
if (_ofd.ShowDialog() != DialogResult.OK) return;
textBox1.Text = _ofd.SafeFileName;
_path = _ofd.FileName;
}
private void button2_Click(object sender, EventArgs e)
{
var allLinesFromFile = File.ReadAllLines(_path);
progressBar1.Minimum = 0;
progressBar1.Maximum = allLinesFromFile.Length;
Task.Factory.StartNew(() => Parallel.ForEach(allLinesFromFile, DoSomething));
while (progressBar1.Value < progressBar1.Maximum) //there has to be a better way to do this...
{
MessageBox.Show("Please wait.", "Record Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
//some processes here which should only take place after all threads are complete.
var postingComplete = MessageBox.Show("The posting is complete!", "Record Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
if (postingComplete == DialogResult.OK) Environment.Exit(0);
}
private void DoSomething(string record)
{
//some string manipulation and server transactions here
BeginInvoke(new BarDelegate(() => progressBar1.Increment(1)));
}
}
【问题讨论】:
-
您是为进度条提供其值的人 - 因此,当您达到 100 时,调用您想要执行的方法。首先,您不需要 TaskFactory。
-
第三 - 有多少行?似乎显示消息框比处理本身需要更多时间
-
您可以编码
ValueChanged事件并检查Value == Maximum -
消息框是否覆盖进度条?
-
@ShannonHolsinger 我使用了TaskFactory 来防止parallel.foreach 阻塞UI 线程。有数十万行。当您考虑服务器事务时,该程序可能需要 10-15 分钟来处理。另外,我设法让消息框不覆盖栏。
标签: c# multithreading events