Reputation: 45
In WinForms application I start worker thread that adds data to root a XElement
.
Then in main thread I need to wait while worker thread finishes it's work (to get complete XElement
), and output this XElement to a textarea
.
If I call .Join()
on the main thread - it freezes until another thread stops (and user can't click any button on the main form).
Is it possible to unblock main thread while waiting for another thread to finish it's work??
I've tried:
1.
BeginInvoke(new Action(() => {
XmlManager.whReady.WaitOne();
xDocString = xResultDoc.ToString();
}));
2.
string xDocString = String.Empty;
new Thread(() => { xDocString = XelementToString(); }).Start();
txtXmlTree.Text = xDocString;
public string XelementToString() {
XmlManager.whReady.WaitOne();
return xResultDoc.ToString();
}
But it had no effect.
EventWaitHandle XmlManager.whReady.WaitOne();
is being .Set()
in the worker thread just before it closes.
Upvotes: 2
Views: 1462
Reputation: 13976
Yes, you can use async/await
string docString = await Task.Run(() => {
XmlManager.whReady.WaitOne();
return xResultDoc.ToString();
}).ConfigureAwait(true);
//Execution flow will resume here once the thread is done.
....
//Now do something here with the text (e.g. display it).
...
For example, if you want to run this on a button click, you would have (note the async modifier):
private async void button1_Click(object sender, EventArgs e)
{
...The code above goes here...
}
As to why your code is not working as expected (both of your attempts):
xDocString
ready to use. It doesn't work that way. By the time this line is executed txtXmlTree.Text = xDocString;
the thread may or may not have finished executing (most likely not finished). I hope now you see why await
is a way better option. You don't have to synchronize your workers with the main thread, you don't have worry about context switching and making sure UI code executes on the UI thread.
Upvotes: 1
Reputation: 85
You can use BackgroundWorker class since it's a WinForm application.
The BackgroundWorker will let the sub-task to be run in the background, and notify the main form on it's completion (as well as progress, if needed), so the main form will be able to display the output in the text area once the sub-task is complete.
Upvotes: 0