【发布时间】:2015-09-18 13:46:03
【问题描述】:
我希望我的程序在下面一行之后等待
frmProgressBarObj = PullMSI.ExtractByMSIName("products.txt", false);
如上方法是通过 StartProcessWithProgress() 方法在内部调用线程。我希望在执行 //code logic -2 行之前完成该线程。同时,它不应该停止由 frmProgressBar.UpdateProgress() 完成的 UI 更新。我该怎么做呢?
namespace NS1
{
public partial class frmMain : Form
{
private void button1_Click(object sender, EventArgs e)
{
frmProgressBar frmProgressBarObj = PullMSI.ExtractByMSIName("products.txt", false);
//code logic - 2
MessageBox.Show("This is executing immediately.
I want to wait until above thread is complete");
}
}
public partial class frmProgressBar : Form
{
public void UpdateProgress(String strTextToDisplayOnProgress)
{
progressBar1.BeginInvoke(
new Action(() =>
{
progressBar1.Value++;
lblFileName.Text = strTextToDisplayOnProgress;
if (progressBar1.Value == progressBar1.Maximum)
{
this.Hide();
}
}));
}
public delegate void DelProgress();
public void StartProcessWithProgress(DelProgress delMethodCode, int maxCount)
{
InitializeProgress(maxCount);
Thread backgroundThread = new Thread(new ThreadStart(delMethodCode));
backgroundThread.Start();
}
}
public static class PullMSI
{
public static frmProgressBar ExtractByMSIName(String strProductFilePath, bool reNameMSI)
{
frmProgressBar frmProgressBar = new frmProgressBar();
frmProgressBar.StartProcessWithProgress(() =>
{
//StreamRader sr declaration and other code
while (!sr.EndOfStream)
{
//logic here
frmProgressBar.UpdateProgress("Copying sr.msiname");
}
}, 2);
return frmProgressBar;
}
}
}
【问题讨论】:
-
用户界面?这是一个控制台应用程序。
-
我的错。抱歉,为了简化代码,我只是将所有类放在控制台应用程序中,以便我可以轻松地在这里发布。但它的 Windows 窗体应用程序和进程在按钮单击时开始。
-
您可以使用以下任何一种:1) TPL 与任务继续 2) 重置事件 (ManualResetEventSlim/AutoResetEventSlim) 3) 使用其他机制,例如 Semaphore(强烈建议您不要这样做) 4) async/如果您正在运行.Net 4.5+,请等待。 5)生产者/消费者(对您的用例来说过度杀伤力)。基本上有多种方法可以做到这一点。阅读这些内容,然后选择一个你最喜欢的。
-
其实我之前没有使用过这些技术,需要时间来学习。客户的期望困扰着我:(任何代码示例都会有很大帮助。
-
您不能在 UI 事件处理程序中等待 - 它是一个状态机,必须及时为其输入队列提供服务。带有事件/信号量的阻塞等待根本不可用。像 Invoke/BeginInvoke 这样的消息信号系统更加健全。
标签: c# .net multithreading task threadpool