收益返回UnityWebRequest.SendWebRequest

时间:2019-09-18 09:00:59

标签: c# unity3d coroutine

在我的应用程序中,有几个协同例程正在并行下载文件,并且它们有可能尝试将同一文件下载到同一路径-导致冲突和访问异常。我尝试通过使用静态集合private static List<string> filesBeingDownloadedNow = new List<string>();解决此问题,该集合为当前正在下载的文件保存了filePath。

它看起来像这样:

private static List<string> filesBeingDownloadedNow = new List<string>();

private IEnumerator DoDownloadCoroutine(string url, string filePath)
{
    filesBeingDownloadedNow.Add(filePath);
    var webRequest = new UnityWebRequest(url)
    {
        method = UnityWebRequest.kHttpVerbGET,
        downloadHandler = new DownloadHandlerFile(filePath)
        {
            removeFileOnAbort = true
        }
    };
    yield return webRequest.SendWebRequest();
    if (webRequest.isNetworkError || webRequest.isHttpError)
    {
        // do something if the file failed to download
    }
    else
    {
        // do something with the downloaded file
    }
    filesBeingDownloadedNow.Remove(filePath);
}

和其他地方:

if (filesBeingDownloadedNow.Contains(filePath))
{
    // start another coroutine which simply waits until 
    // filesBeingDownloadedNow doesn't contain filePath anymore 
    // and then works with the downloaded file 
    // as if this coroutine downloaded it itself
}
else
{
    StartCoroutine(DoDownloadCoroutine(url, filePath));
}

现在,这工作得很好,但是在极少数情况下,可以在文件下载协程完成之前销毁运行此协程的gameObject。因此,yield return webRequest.SendWebRequest();将是这里有史以来的最后一件事,无法检查成功或失败,并且永远无法达到filesBeingDownloadedNow.Remove(filePath);

我对此进行了测试,看来UnityWebRequest.SendWebRequest仍会完整下载文件-但是,尚不清楚何时结束或是否成功下载了文件。它只是“在以太里迷路了”。

我可以简单地尝试围绕File.Open进行异常处理,或者我想对下载的文件进行其他任何处理(实际上无论如何都应该这样做)。但是,UnityWebRequest不允许处理异常,因为它是用yield return调用的。

即使在调用webRequest.SendWebRequest();之前,我也会检查文件if (File.Existst(filePath))是否已存在,但是如果2个不同的UnityWebRequests尝试几乎同时下载同一文件,这也无济于事。可能是第一个UnityWebRequest只是刚刚连接到服务器,还没有在filePath上创建文件,第二个协程将看到该文件不存在,并假设现在没有人下载它,并且仍然尝试使用webRequest.SendWebRequest();下载,导致冲突和我无法处理的异常。

因此,基本上,有多种因素结合在一起:

  • 可以在任何时候默默地关闭例程,而无需进行“最终”清理或清除之前的任何事情
  • UnityWebRequest.SendWebRequest不允许处理异常(?)
  • 下载的文件实际出现在该位置之前的延迟使得无法检查文件是否已经下载

坦白说,我也确实不喜欢这里的静态列表,但是似乎文件仍然是全局资源,因此使其成为非静态无法解决任何问题。无论我对该列表进行什么操作,UnityWebRequest.SendWebRequest都会继续自行下载文件。

1 个答案:

答案 0 :(得分:2)

您从不等待下载处理程序完成,如果您尝试在下载处理程序完成之前使用它,有时会导致奇怪的行为,在处理程序isDone标志为true之前,最好产生null,即它完成处理下载的数据,取决于其类型。

是,请求完成下载,但有时处理程序未完成其“处理”,即完成下载的同一瞬间。

UnityWebRequest webRequest = UnityWebRequest.Get(url);
webRequest.downloadHandler = new DownloadHandlerFile(filePath) { removeFileOnAbort = true };

// 1) Wait until the download is done.
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || webRequest.isHttpError)
{
    // do something if the file failed to download
}
else
{
    // 2) Wait until the handler itself finishes.
    while (!webRequest.downloadHandler.isDone)
        yield return null;

    // Now you can safely do something with the downloaded file
}
相关问题