Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by thrmotta · Jun 17, 2015 at 05:14 PM · dllthreadsthreadingthread

How to prevent heavy method calculation from locking Unity up?

Hello, everyone!

Right now Im having an issue with a method, called from a DLL, in which it can take a long time before this method finishes its calculation and in the mean time I simply cannot use anything on Unity.

I tried using a thread (see below) so that Unity could continue its tasks while my method calculation was being done, but that didnt work out.

  IntPtr resultPointer = default(IntPtr);
             Debug.Log( "Startin thread... " );
             System.Threading.Thread thread = new System.Threading.Thread(
                 () =>
                 {
                     resultPointer = computeMinBox3D( _pointsFloatVector.Length, _pointsFloatVector, 8 );
                 }
                 );
             thread.Start( );
             thread.Join( );
             Debug.Log( "Thread work done!" );

I read some of the coroutine documentation and figured it wouldnt solve my problem either.

My second try is the following:

 private IEnumerator YieldComputeMinBox3D( int pointsFloatVectorLength, float[] pointsFloatVector, int numThread )
         {
             _resultPointer = computeMinBox3D( pointsFloatVectorLength, pointsFloatVector, numThread );
 
             yield return null;
         }

Altough this one does prevent Unity from locking up it also doesnt execute the method correctly, it seems to just skip its heavy calculation completely and doesnt continue where it is supposed to. What am I missing here?

Extra question: The method Im calling is already multithreaded. Would this be a problem?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Dave-Carlile · Jun 17, 2015 at 06:06 PM

In your thread version you're calling thread.Join. This waits for the thread complete, which defeats the purpose.

You need to start the thread and let it run in parallel. At some point, possibly multiple frames in the future, that thread will complete its work and you can grab the result. You'll need a way to communicate back to the main thread that the thread is complete. Then you get into synchronization issues and such which are beyond the scope here.

.NET has Tasks that would make this a bit easier, but I don't think the version of Mono that Unity uses has those? Not 100% sure about that though.

Your only other option is to manually split the work across multiple frames, with coroutines or something, but that doesn't seem very feasible unless the dll is yours and you can modify it.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image thrmotta · Jun 17, 2015 at 06:12 PM 0
Share

I was going for async threads with Tasks right now but System.Threading doesnt have the Task class.

Ill try something with the sync issues before modifying my dll (I do have its souce code).

If I really need to touch the dll, would you have any example on how to modify it to split work accross multiple frames?

Thanks!

avatar image Dave-Carlile · Jun 17, 2015 at 06:21 PM 1
Share

Split compute$$anonymous$$inBox3D into multiple pieces that each run quickly. Use a coroutine in Unity that calls the first piece, yields to the next frame, calls the second piece, etc. If you set up the new compute$$anonymous$$inBox3D right you can just call the same function and pass in a state enum or something. Or you might need to pass a class back and forth if there's more state that needs to be preserved between executions.

But if you're going to go through all that trouble, you might as well code it in C# (I assume it isn't already because of your use of IntPtr) in Unity and turn it into a proper coroutine.

avatar image SteveFSP · Jun 17, 2015 at 07:39 PM 1
Share

The accepted answer to this question gives a good overview with example code for how to thread in Unity. It includes how to poll the threaded job for completion. (See near the bottom of the answer.) If you are doing this in the Unity Editor rather than in play mode, then the EditorApplication.update callback can be used ins$$anonymous$$d of $$anonymous$$onoBehaviour.Update().

The thing to remember about coroutines is that they are really just a way to flexibly schedule progressive tasks. ($$anonymous$$g. Do this, wait a bit, then do that, wait again, then do this final thing.) Everything they do still happens on the main application thread. So if there is heavy work in a section of code in a co-routine it will still block the main application.

avatar image thrmotta · Jun 18, 2015 at 05:33 PM 0
Share

Although I had already seen that question several times, it took me some time to decide to try it, but once I did, it did solve my problem :)

In the end I had to split my heavy calculation method in 3 steps:

->PreProcess ->DLL call in a new thread (where unity was freezing) ->PostProcess

Since this method is triggered by a UI button, I decided to make the following:

 private void $$anonymous$$anageThreadedJob( ref bool apply, ThreadedJob job, Action PreProcess, Action PostProcess )
         {
             if( apply && job == null )
             {
                 PreProcess( );
                 apply = false;
             }
 
             if( job != null )
             {
                 if( job.Update( ) && _threadWorkIsDone == false )
                 {
                     PostProcess( );
                     PostProcessGenerate( );
                     _threadWorkIsDone = true;
                 }
             }
         }

This way I can pass multiple dll calls to threads in a generic way.

Thanks everyone for the help!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

What does new Thread do, and how many threads are too many? 1 Answer

will monobehaviour stay alive after DOTS? 0 Answers

Job System without using the main thread 1 Answer

LobbyHook doesn't give clients variables 0 Answers

Return value from coroutine to non monobehaviour 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges