Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
0
Question by DeanShea · Jan 02 at 10:58 AM · asyncthreading

How to handle expensive and frequent functions without blocking the main thread?

I have an A* algorithm that I want to run a lot.

 public static event Action<List<Position>> FoundPath = delegate { };
 
 public void A*(List<Vector3> path)
 {
     while(!IsSorted(path) || !end)
     {
         bogosort(path)
     }
     if(IsSorted(path))
     {
         FoundPath(path)
     }
 }

Bogosort is expensive, doesn't always have a solution and can run for so long that by the time it has a solution I don't need it anymore. What is the simplest and most consistent way to handle this use case?

  • I have tried coroutines but I want such a large and arbitrary amount of attempts that yielding is awkward

  • I have tried jobs but have found updating a parameter on a job to be inconsistent and whimsical (I haven't gotten locks, volatile or Interlock to work effectively)

Any help would be appreciated thanks.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Llama_w_2Ls · Jan 02 at 01:10 PM

You can run the code asynchronously. This will take the same amount of time, however the code will run on a separate thread, meaning your application won't hang whilst it is running.


Setting up a thread/task is still a costly process, so I would try not to create threads every frame, instead, put delays.


For example: The A* function will be written as:

  public async void A*(List<Vector3> path)
  {
      while(!IsSorted(path) || !end)
      {
          await bogosort(path)
      }
      if(IsSorted(path))
      {
          FoundPath(path)
      }
  }

instead. Notice the async keyword before void.

Now, you'll also need to make bogosort an async method too. E.g:

 async void bogosort()
 {
      await Task.Run(() =>
      {
           // Put all code inside this block..
      });
 }

The await block allows you to wait till the code has finished execution, and the Task.Run block allows you to offload some code to another thread.


Be careful when threading code, as most of the Unity API isn't allowed to be called from another thread.

@DeanShea

Comment
Add comment · Show 1 · 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 DeanShea · Jan 03 at 04:18 AM 0
Share

I just realised I didn't mention in the original question that I do not want to block main, sorry for that. For the edited question this solution requires more context on how to handle the await and it also doesn't offer any advice on how to handle safely ending outdated calls. @Llama_w_2Ls

avatar image
0

Answer by DeanShea · Jan 04 at 03:14 AM

For context my current solution is

 public class PathScheduler
 {
         public JobHandle current_job;
         public FindPath path;
         public Guid path_id;
     
         public void ScheduleFindPath((List<Vector3> m_list)
         {
             path = new Map.FindPath(m_list);
             path_id = path.m_id;
             current_job = path.Schedule();
             Map.FindPath.current.Add( path_id);
         }
         public void EndJob()
         {
             Map.FindPath<T>.current.Remove(path_id);
          }
 }
 public struct FindPath: IJob
 {
             public static event Action<List<Vector3>> FoundPath = delegate { };
             public static HashSet<Guid> current = new HashSet<Guid>();
             public Guid m_id;
             public FindPath(List<Vector3> given_list)
             {
                 m_id = Guid.NewGuid();
                 m_list = given_list;
             }
     
             public void Execute()
             {
                  while(!IsSorted(path) && current.Contains(m_id) )
                  {
                      bogosort(path)
                  }
                  if(IsSorted(path))
                  {
                      FoundPath(path)
                  }
             }
     }

I realise my solution isn't thread safe/best practice (using static variables in multiple threads). So far I've had no runtime errors, all the functionality and consistency that I want, no alternatives and better things to do. So if there is a solution that is thread safe, killable, doesn't block main and allows a loop to run a lot/arbitrary amount of times each frame, let me know.

Comment
Add comment · 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

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

132 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 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 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 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 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 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

Using AsyncOperation for our own services 4 Answers

C# How do I read an external text file asynchronously in Unity? 2 Answers

Unity Asynchronous Socket Client - Threading Problem 2 Answers

How to do async operation on appliation quit ? 1 Answer

LoadLevel Async 2 Answers


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