首先是问题: 我可以在未标记为 async 的函数中使用 await 吗?
现在的细节。我正在读这篇文章 Hololens- Capturing Photo...正如您所看到的,作者发布了一些代码。 其中包括
void Start ()
{
getFolderPath();
while (!haveFolderPath)
{
Debug.Log("Waiting for folder path...");
}
Debug.Log("About to call CreateAsync");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
Debug.Log("Called CreateAsync");
}
async void getFolderPath()
{
StorageLibrary myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
Windows.Storage.StorageFolder savePicturesFolder = myPictures.SaveFolder;
Debug.Log("savePicturesFolder.Path is " + savePicturesFolder.Path);
folderPath = savePicturesFolder.Path;
haveFolderPath = true;
}
现在注意getFolderPath如何返回void(作为事件处理程序),但是文档说这些方法是无法等待的。作者改为等待使用while循环。
但是,如果我这样做
void Start ()
{
await getFolderPath();
Debug.Log("About to call CreateAsync");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
Debug.Log("Called CreateAsync");
}
//Notice how now it returns Task
async Task getFolderPath()
{
StorageLibrary myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
//.....
}
我可以这样做吗? (注意Start()不是Async)
答案 0 :(得分:3)
人们往往会忘记async
和await
背后的内容。
不,您不能 await
的方法不是async
,但您可以在返回的ContinueWith
上致电Task
并提供仅在任务完成时执行的显式继续:
class Example
{
public void Start()
{
getFolderPath()
.ContinueWith(t =>
{
Console.WriteLine("...");
});
}
async Task getFolderPath()
{
await Task.Delay(1000);
}
}
这相当于
class Example
{
public async Task Start()
{
await getFolderPath();
Console.WriteLine("...");
}
async Task getFolderPath()
{
await Task.Delay(1000);
}
}
答案 1 :(得分:0)
如果不将方法标记为await
,则无法async
函数调用。所以你的第二个例子不会编译。但您可以将Start方法标记为async
。
Async await
是一种等待执行函数的非阻塞方法。在这种情况下,执行将在GetFolderPath
方法中的await处停止,但是这将等待,Start方法中的执行将继续。我假设,因此,作者使用while loop
等待getFolderPath
的执行完成。
答案 2 :(得分:0)
第一个问题的答案是不,你不能。来自官方documentation
await
只能用于async
修改的异步方法 关键词。这种方法,使用async修饰符和 通常包含一个或多个await表达式,被称为 异步方法。
如果要在start方法中等待执行异步方法getFolderPath
,则需要将签名更新为
public async Task Start ()
{
await getFolderPath();
Debug.Log("About to call CreateAsync");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
Debug.Log("Called CreateAsync");
}
在async await
上下文中,Task
作为返回类型,表示该任务不返回值,该值等同于同步方法中的void
。例如,如果您需要从异步任务返回string
,则需要public async Task<string> GetFoo()
。
总的来说,我认为您正在查看的示例中的代码需要进行一些审核。
答案 3 :(得分:0)
您可以明确等待GetFolderPath
方法完成:
void Start ()
{
getFolderPath().Wait();
Debug.Log("About to call CreateAsync");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
Debug.Log("Called CreateAsync");
}
//Notice how now it returns Task
async Task getFolderPath()
{
StorageLibrary myPictures = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
//.....
}
但是你正在以异步方式转换异步方法,因为Wait
是一种阻塞方法(但这就是在while循环中发生的事情)。
如果您的目标是使操作保持异步,则必须遵循DanielOrmeño的建议:
async Task Start ()
{
await getFolderPath();
Debug.Log("About to call CreateAsync");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
Debug.Log("Called CreateAsync");
}