开发者

Basic thread question

开发者 https://www.devze.com 2023-02-14 13:38 出处:网络
If i have a class public Class foo { public foo() { myclass = new myclass(param) myclass.initiateState(); val = myclass.getValues();

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

0

精彩评论

暂无评论...
验证码 换一张
取 消