我有一个蒙特卡洛仿真运行跨多个线程与进度条通知用户如何去。进度条管理使用Invoke在单独的线程中完成,但表单未更新。C#,多线程 - 表单不更新
这里是我的代码:
Thread reportingThread = new Thread(() => UpdateProgress(iSims, ref myBag));
reportingThread.Priority = ThreadPriority.AboveNormal;
reportingThread.Start();`
,这里是被调用的函数:
private void UpdateProgress(int iSims, ref ConcurrentBag<simResult> myBag)
{
int iCount;
string sText;
if (myBag == null)
iCount = 0;
else
iCount = myBag.Count;
while (iCount < iSims)
{
if (this.Msg.InvokeRequired)
{
sText = iCount.ToString() + " simultions of " + iSims + " completed.";
this.Msg.BeginInvoke((MethodInvoker) delegate() { this.Msg.Text = sText; this.Refresh(); });
}
Thread.Sleep(1000);
iCount = myBag.Count;
}
}
我都用了Application.DoEvents()和this.refresh(),试图迫使要更新的表单,但没有任何反应。
更新:这是因为你可以看到,有一些更新的表格我调用调用之前,他们都做工精细的过程调用上述功能
private void ProcessLeases(Boolean bValuePremium)
{
int iSims, iNumMonths, iNumYears, iIndex, iNumCores, iSimRef;
int iNumSimsPerThread, iThread, iAssets, iPriorityLevel;
string sMsg;
DateTime dtStart, dtEnd;
TimeSpan span;
var threads = new List<Thread>();
ConcurrentBag<simResult> myBag = new ConcurrentBag<simResult>();
ConcurrentBag<summaryResult> summBag = new ConcurrentBag<summaryResult>();
this.Msg.Text = "Updating all settings";
Application.DoEvents();
ShowProgressPanel();
iSims = objSettings.getSimulations();
iNumCores = Environment.ProcessorCount;
this.Msg.Text = "Initialising model";
Application.DoEvents();
iNumSimsPerThread = Convert.ToInt16(Math.Round(Convert.ToDouble(iSims)/Convert.ToDouble(iNumCores), 0));
this.Msg.Text = "Spawning " + iNumCores.ToString() + " threads";
for (iThread = 0; iThread < iNumCores; iThread++)
{
int iStart, iEnd;
if (iThread == 0)
{
iStart = (iThread * iNumSimsPerThread) + 1;
iEnd = ((iThread + 1) * iNumSimsPerThread);
}
else
{
if (iThread < (iNumCores - 1))
{
iStart = (iThread * iNumSimsPerThread) + 1;
iEnd = ((iThread + 1) * iNumSimsPerThread);
}
else
{
iStart = (iThread * iNumSimsPerThread) + 1;
iEnd = iSims;
}
}
Thread thread = new Thread(() => ProcessParallelMonteCarloTasks(iStart, iEnd, iNumMonths, iSimRef, iSims, ref objDB, iIndex, ref objSettings, ref myBag, ref summBag));
switch (iPriorityLevel)
{
case 1: thread.Priority = ThreadPriority.Highest; break;
case 2: thread.Priority = ThreadPriority.AboveNormal; break;
default: thread.Priority = ThreadPriority.Normal; break;
}
thread.Start();
threads.Add(thread);
}
// Now start the thread to aggregate the MC results
Thread MCThread = new Thread(() => objPortfolio.MCAggregateThread(ref summBag, (iSims * iAssets), iNumMonths));
MCThread.Priority = ThreadPriority.AboveNormal;
MCThread.Start();
threads.Add(MCThread);
// Here we review the CollectionBag size to report progress to the user
Thread reportingThread = new Thread(() => UpdateProgress(iSims, ref myBag));
reportingThread.Priority = ThreadPriority.AboveNormal;
reportingThread.Start();
// Wait for all threads to complete
//this.Msg.Text = iNumCores.ToString() + " Threads running.";
foreach (var thread in threads)
thread.Join();
reportingThread.Abort();
this.Msg.Text = "Aggregating results";
Application.DoEvents();
this.Msg.Text = "Preparing Results";
Application.DoEvents();
ShowResults();
ShowResultsPanel();
}
- 在每一种情况下,我我正在使用Application.DoEvents()来更新。
myBag是一个ConcurrentBag,每个蒙特卡罗线程都会将结果转储到这个ConcurrentBag中。通过使用Count方法,我可以看到有多少模拟完成并更新了用户。
你会介意发布一个完整的代码块来测试吗? –
@Leonardo - 上面添加的代码。 – John
抱歉坚持,但仍然无法测试。什么是“this.Msg”?它是一个控件吗? –