If i have a class
public Class foo
{
public foo()
{
myclass = new myclass(param)
myclass.initiateState();
val = myclass.getValues();
}
}
Class.initiateState()
is a lengthy process which is running in my GUI constructor which I wanted to start running with a thread, however the next line goes to the same class to get some data back, yet if I run the firs开发者_开发知识库t line in a new thread then this gets executed before it can finish.
How can I solve this problem?
Make a BackgroundWorker
.
Inside the DoWork
event method, add the myClass.initiateState()
call. Inside the RunWorkerCompleted
event method, call myClass.getValues();
This will cause initiateState
to run on a background thread, and when finished will fire getValues
on the GUI thread.
Also, note that in C# it's normal to start method names with an uppercase letter, compared to Java. So the methods should have the names InitiateState
and GetValues
:)
Easiest way is to do:
public Class foo
{
public foo()
{
myclass = new myclass(param)
new Action( () => myclass.initiateState() ).BeginInvoke(initiateStateFinished, null)
}
private void initiateStateFinished(IAsyncResult ar)
{
val = myclass.getValues();
//other actions
}
}
or even shorter
public foo()
{
myclass = new myclass(param)
new Action( () => myclass.initiateState() )
.BeginInvoke(_ => val = myclass.getValues(), null)
}
So, you want to execute BOTH
myclass.initiateState();
val = myclass.getValues();
in a new thread (with the val being a return value)?
You can do that easily using .NET 4.0 Tasks
, as such:
var someBackgroundTask = new System.Threading.Tasks.Task<*return type of GetValue()*>(() =>
{
myclass.initiateState();
return myclass.getValue();
});
someBackgroundTask.Start();
and later use someBackgroundTask.Result
to get the, well, result. The only problem you'll have is you'll need to wait (or check at key points) to see if the Task
has finished. You can use someBackgroundTask.IsCompleted
to check if it's still working or someBackgroundTask.Wait()
to wait for it to finish.
EDIT: Than again, the suggestions above are probably better. ;)
From the example given it seems that the whole foo
class should be ran in a separate thread. For the sake of being applicable to other circumstances I will assume there is something else in foo
which shouldn't be run as a different thread.
First create a DoWork method in foo
:
private void DoWork() {
myclass = new myclass(param);
myclass.initiateState();
val = myclass.getValues();
}
Then change the constructor to run that as a thread:
public foo() {
Thread workerThread = new Thread(this.DoWork);
/* ... do other stuff ... */
}
Take a look at this: http://msdn.microsoft.com/en-us/library/7a2f3ay4.aspx
精彩评论