我有以下情况:
同时我想更新进度条或具有某种状态的文本框 - 所以我尝试了以下内容:
在这两种情况下,我的GUI都不会更新,直到获取任务结果。如果你能指出我正确的方向,我将非常感激。
private void button1_Click ( object sender, EventArgs e )
{
bw.RunWorkerAsync(); // Updates a textbox
Task<bool> test2 = new Task<bool>( () => _AuthHandler( sender, e, textBox1.Text, textBox2.Text ) );
try
{
test2.Start();
bool result = test2.Result;
//bool result = _AuthHandler.Invoke( sender, e, textBox1.Text, textBox2.Text );
if ( result )
{
//Do Somethin..
}
}
catch(Exception e) {
//Do Something
}
}
// -------BW TEST CODE --------//
public void smthn ()
{
textBox3.Text += ".";
}
void bw_DoWork ( object sender, DoWorkEventArgs e )
{
for(int i = 0;; i++)
{
bw.ReportProgress( i );
Thread.Sleep( 250 );
}
}
bool result = false;
void bw_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e )
{
MessageBox.Show( "Result Set" );
result = (bool)e.Result;
}
void bw_ProgressChanged ( object sender, ProgressChangedEventArgs e )
{
if ( textBox3.InvokeRequired )
{
this.Invoke( new Action( smthn ) );
}
else
{
smthn();
}
}
答案 0 :(得分:1)
您正在阻止UI线程,直到某些非UI工作完成。不要那样做。让UI线程做UI工作,安排在另一个线程中完成非UI工作,然后让它做什么都不做;它将回到处理其他UI事件。
BackgroundWorker专门用于让UI执行一些非UI工作,并使用进度或结果更新UI。让BGW的DoWork
方法完成您的实际工作,更新更新的处理程序中的进度条,并在完成的处理程序中显示结果。 BGW将负责在UI线程中运行除DoWork
事件之外的所有事件,因此您无需手动调用UI线程。
您的代码无法正常工作的原因是您通过等待任务来阻止UI线程,并且由于它被阻止,因此从BGW的进度事件安排的UI更新没有机会运行,直到整件事情结束了。
答案 1 :(得分:0)
您的网络任务应该使用DoWork()
方法在后台线程中运行,根据需要调用ReportProgress()
然后,在您的主UI线程中,订阅ProgressChanged
事件,并且更新您的ProgressBar
答案 2 :(得分:0)
谢谢大家......我意识到我阻止了UI线程。所以我制作了一个通用课程,包括两个背景工作者,进度事件,酒吧和一个完成的事件 - &gt;它调用后处理功能。我想这是大多数人推荐的方法。
虽然有其他选择吗?那么async / await