Reputation: 9252
The below code does not work in 'real time'. The intention is, when the button is clicked, validate a set of data on the background thread. I cannot allow true 'submission' until all of the data is validated, but I do want the textbox to update in real time.
Instead, the textbox gets updated with the odd numbers, all at once.
I imagine what is happening is that the task.Wait is blocking the observable since I am observing on the main thread, but I cannot see a way around this as I need to update on the main thread.
(Obviously this is just a proof of concept)
Somewhat related note - is this code guaranteed to threadsafe? Thanks.
private Subject<int> _subject;
public Form1()
{
InitializeComponent();
}
private int sleep = 2000;
private int i = 0;
private void LongRunningValidation(int num)
{
if (num % 2 == 0) return;
Thread.Sleep(sleep * (i++));
_subject.OnNext(num);
}
private ConcurrentBag<int> _bag;
private void simpleButton1_Click(object sender, EventArgs e)
{
_subject = new Subject<int>();
_subject.SubscribeOn(Scheduler.TaskPool).ObserveOn(SynchronizationContext.Current).Synchronize().Subscribe(UpdateTextBox);
_bag = new ConcurrentBag<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
if(Validate())
{
//submit
}
}
private bool Validate()
{
var task = Task.Factory.StartNew(StartValidationAsync);
task.Wait();
return true;
}
private void StartValidationAsync()
{
Parallel.ForEach(_bag, LongRunningValidation);
}
private void UpdateTextBox(int i)
{
textEdit1.Text = textEdit1.Text + "," + i;
}
}
Upvotes: 0
Views: 1911
Reputation: 1789
Your Validate
method not async and as you say block main thread. Try use events:
public delegate void ValidatedHandler(bool validate);
public event ValidatedHandler Validated;
private void Validate()
{
var task = Task.Factory.StartNew(StartValidationAsync);
if (Validated != null)
Validated(true);
}
And subscribe on event:
private void simpleButton1_Click(object sender, EventArgs e)
{
_subject = new Subject<int>();
_subject.SubscribeOn(Scheduler.TaskPool).ObserveOn(SynchronizationContext.Current).Synchronize().Subscribe(UpdateTextBox);
_bag = new ConcurrentBag<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
this.Validated += OnValidated;
}
public void OnValidated(bool validate)
{
if(validate)
{
//submit
}
}
Upvotes: 1
Reputation: 872
Windows Forms does not automatically update the UI, even if you are running a background thread. Try calling Update() on whatever you want to update.
Upvotes: 0