基本上我想在FormMain(WindowsForm)上更新ProgressBar UI对象。我使用的是.NET 4.0
以下是Form1.Designer.cs中的代码
namespace ProgressBarApp
{
public partial class Form1 : Form
{
private System.Windows.Forms.ProgressBar curProgressBar;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
CustomProcess theProcess = new CustomProcess();
theProcess.Process();
}
}
}
以下是CustomProcess.cs的定义
namespace ProgressBarApp
{
class CustomProcess
{
public void Process()
{
for (int i = 0; i < 10; i++)
{
Task ProcessATask = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000); // simulating a process
}
);
Task UpdateProgressBar = ProcessATask.ContinueWith((antecedent) =>
{
// how do i update the progress bar object at UI here ?
}
);
}
}
}
}
答案 0 :(得分:6)
您可以使用SynchronizationContext
执行此操作。要将其用于Task
,您需要创建一个TaskScheduler
,您可以通过调用TaskScheduler.FromCurrentSynchronizationContext
来执行此操作:
Task UpdateProgressBar = ProcessATask.ContinueWith(antecedent =>
{
// you can update the progress bar object here
}, TaskScheduler.FromCurrentSynchronizationContext());
仅当您直接从UI线程调用Process()
时,此方法才有效。
答案 1 :(得分:4)
如何使用System.Reactive.Linq:
<强> [UPDATE] 强>
using System.Reactive.Linq;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
//private System.Windows.Forms.ProgressBar curProgressBar;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
CustomProcess theProcess = new CustomProcess();
var x = Observable.FromEventPattern(theProcess, "TaskCompleted");
curProgressBar.Maximum = 4;
x.Subscribe((a) =>
{
curProgressBar.Value = ((CustomProcess)a.Sender).Counter;
});
theProcess.Process();
}
}
class CustomProcess
{
public int Counter { get; set; }
public event EventHandler TaskCompleted = OnTaskCompleted;
private static void OnTaskCompleted(object sender, EventArgs e)
{
((CustomProcess)sender).Counter++;
}
public void Process()
{
for (int i = 0; i <= 3; i++)
{
Task ProcessATask = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000); // simulating a process
}
);
var awaiter = ProcessATask.GetAwaiter();
awaiter.OnCompleted(() =>
{
TaskCompleted(this, null);
});
}
}
}
}