Сопрограмма ждать метода, прежде чем продолжить - PullRequest
0 голосов
/ 02 октября 2019

У меня есть сопрограмма, которая загружает видео, записывает его в память, а затем воспроизводит его.

IEnumerator DownloadVideo(string url) {
    UnityWebRequest www = UnityWebRequest.Get(url);
    yield return www.SendWebRequest();
    byte[] result = www.downloadHandler.data;
    File.WriteAllBytes(path, result);
    StartCoroutine(PlayVideo(path, 3));
}

IEnumerator PlayVideo(string url, float delayTime = 0) {
    yield return new WaitForSeconds(delayTime);
    player.url = url;        
    player.Prepare();        
    while (!player.isPrepared) yield return null;
    player.Play();
}

Проблема в том, что мне нужно установить этот аргумент delayTime в PlayVideoсопрограмма, потому что File.WriteAllBytes(path, result) требуется некоторое время, чтобы закончить, и если я сразу начну воспроизводить видео, оно не будет воспроизводиться правильно.

Вопрос прост: в сопрограмме DownloadVideo, как я могу ждать, покаFile.WriteAllBytes(path, result) закончить, чтобы позвонить StartCoroutine(PlayVideo(path))?

Ответы [ 4 ]

0 голосов
/ 03 октября 2019

File.WriteAllBytes - это синхронный метод, поэтому он не является проблемой для вашего кода. File.WriteAllBytes не требует дополнительного времени для завершения, когда завершается выполнение этой строки кода. Вероятно, у вас есть другой процесс, блокирующий файл, например антивирус или программа резервного копирования.

0 голосов
/ 02 октября 2019

Мне кажется, проблема в том, что вы не закрываете файл.

File.WriteAllBytes(path, result); не является асинхронным вызовом, поэтому он должен завершить свою работу, прежде чем перейти к следующей строке, которая запускает PlayVideo сопрограмму.

Я бы порекомендовал вам использовать FileStream и обязательно избавиться от потока перед вызовом PlayVideo сопрограммы.

Надеюсь, это поможет.

0 голосов
/ 02 октября 2019

Этот подход, кажется, работает:

IEnumerator DownloadVideo(string url) {
    UnityWebRequest www = UnityWebRequest.Get(url);
    yield return www.SendWebRequest();
    byte[] result = www.downloadHandler.data;
    File.WriteAllBytes(path, result);
    yield return new WaitUntil(() => File.Exists(path));
    StartCoroutine(PlayVideo(path));
}

Очевидно, File.Exists(path) вернет true только тогда, когда WriteAllBytes(path, result) закончится.

0 голосов
/ 02 октября 2019

Вы можете использовать File.WriteAllBytesAsync (документация здесь ).

Тогда вы можете позвонить await File.WriteAllBytesAsync(path, result). Вам также нужно будет сделать вашу DownloadVideo функцию асинхронной. По сути, await говорит: подождите, пока этот вызов не будет выполнен, пока я не перейду дальше в этой функции.

Более подробную информацию об асинхронном программировании в C # можно найти здесь .

...