Saya memiliki coroutine di Unity3D yang mengunduh zip dari server, mengekstraknya ke jalur data persisten, dan memuat isinya ke dalam memori. Alirannya terlihat seperti ini:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Tetapi ExtractZip()
metode (yang menggunakan perpustakaan DotNetZip), adalah sinkron, memakan waktu terlalu lama, dan tidak meninggalkan saya tempat untuk menghasilkan selama proses.
Ini mengakibatkan aplikasi terbunuh (pada perangkat seluler) setiap kali saya mencoba mengekstrak zip besar, yang saya asumsikan karena utas utama menjadi tidak responsif terlalu lama.
Apakah ini sesuatu yang diketahui dilakukan oleh OS seluler (bunuh aplikasi jika bingkai terlalu lama)?
Jadi, saya berasumsi bahwa mengekstraksi zip pada utas terpisah mungkin bisa menyelesaikan masalah, dan tampaknya berhasil. Saya membuat kelas ini:
public class ThreadedAction
{
public ThreadedAction(Action action)
{
var thread = new Thread(() => {
if(action != null)
action();
_isDone = true;
});
thread.Start();
}
public IEnumerator WaitForComplete()
{
while (!_isDone)
yield return null;
}
private bool _isDone = false;
}
Dan saya menggunakannya seperti ini:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Tapi saya masih tidak yakin apakah ini cara terbaik untuk mengimplementasikannya, atau apakah saya perlu mengunci _isDone
(tidak terlalu terbiasa dengan multithreading).
Adakah yang salah dengan ini? Apakah saya melewatkan sesuatu?
sumber
Anda tidak perlu mengunci _isDone, tetapi itu harus ditandai volatile.
sumber