I'm a relatively new to Unity3d C# but not to programming (Java). I'm trying to work with Threads and so far it has been quite successful as it is a lot like Java. But I'm having code lock and I'm trying to figure out why. DownloadStatus is just an enum.
The following code is called from the ThreadPoolCallback:
public static Dictionary<int, int> downloading = new Dictionary<int, int>(); ... //Look on the download list while (true) { foreach (int id in downloading.Keys) { lock(downloading){ Debug.Log("Thread " + threadIndex + " checking id: "+id); if(downloading [id]==(int)DownloadStatus.WAITING){ //This file is waiting downloading [id] = (int)DownloadStatus.DOWLOADING; Debug.Log ("Thread " + threadIndex + " is downloading " + id); //TODO: Actual downloading //Mark as done downloading [id] = (int)DownloadStatus.DONE; Debug.Log ("Thread " + threadIndex + " is done downloading " + id); }else if(downloading [id]==(int)DownloadStatus.DOWLOADING){ Debug.Log ("Thread " + threadIndex + " ignoring "+id+" since is already downloading!"); }else if(downloading [id]==(int)DownloadStatus.DONE){ Debug.Log ("Thread " + threadIndex + " ignoring "+id+" since is already downloaded!"); } } } //If you made it here, there's nothing to process Debug.Log ("Thread " + threadIndex + " closed!"); _doneEvent.Set(); break; } If I comment the lines where I change the value of the dictionary (i.e. downloading [id]=(int)DownloadStatus.DOWLOADING;) I can see the threads going thru all the values in the dictionary. When I don't the thread stops there. The only purpose of this state is to prevent other threads from attempting the same download.
Maybe is just the wrong approach for accomplishing this.
Any idea?
Update
Code to populate downloading:
Retriever.downloading.Add(id,(int)DownloadStatus.WAITING); Where Retriever is the name of the Thread class.
Following the suggestions by KeithS the code changed to:
public static Dictionary<int, int> downloading = new Dictionary<int, int>(); private readonly object syncObj = new object(); ... //Look on the download list foreach (int id in downloading.Keys) { lock(syncObj){ Debug.Log("Thread " + threadIndex + " checking id: "+id); if(downloading [id]==(int)DownloadStatus.WAITING){ //This file is waiting downloading [id] = (int)DownloadStatus.DOWLOADING; Debug.Log ("Thread " + threadIndex + " is downloading " + id); //TODO: Actual downloading //Mark as done downloading [id] = (int)DownloadStatus.DONE; Debug.Log ("Thread " + threadIndex + " is done downloading " + id); }else if(downloading [id]==(int)DownloadStatus.DOWLOADING){ Debug.Log ("Thread " + threadIndex + " ignoring "+id+" since is already downloading!"); }else if(downloading [id]==(int)DownloadStatus.DONE){ Debug.Log ("Thread " + threadIndex + " ignoring "+id+" since is already downloaded!"); } } } //If you made it here, there's nothing to process Debug.Log ("Thread " + threadIndex + " closed!"); _doneEvent.Set(); break; } And here's the output (Have only 2 threads for testing purposes):
914 files to update! Thread 1 started... Thread 2 started... Thread 1 checking id: 2 Thread 1 is downloading 2 Thread 1 is done downloading 2 Thread 1 closed! And basically stays there for ever. Same kind of behavior I had before.