我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
当前回答
添加一个解决方案,最终解决了我的问题,希望能节省别人的时间。
首先阅读Stephen Cleary的几篇文章:
异步和等待 不要阻塞异步代码
在“不要阻塞异步代码”中的“两个最佳实践”中,第一个对我来说不适用,第二个不适用(基本上如果我可以使用await,我就会使用!)。
下面是我的解决方案:将调用包装在一个Task中。运行<>(async () => await FunctionAsync());希望不会再出现僵局。
这是我的代码:
public class LogReader
{
ILogger _logger;
public LogReader(ILogger logger)
{
_logger = logger;
}
public LogEntity GetLog()
{
Task<LogEntity> task = Task.Run<LogEntity>(async () => await GetLogAsync());
return task.Result;
}
public async Task<LogEntity> GetLogAsync()
{
var result = await _logger.GetAsync();
// more code here...
return result as LogEntity;
}
}
其他回答
如果你想运行它同步
MethodAsync().RunSynchronously()
这些windows异步方法有一个漂亮的小方法叫做AsTask()。您可以使用它让方法作为任务返回本身,以便您可以手动调用Wait()。
例如,在Windows Phone 8 Silverlight应用程序中,您可以执行以下操作:
private void DeleteSynchronous(string path)
{
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Task t = localFolder.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask();
t.Wait();
}
private void FunctionThatNeedsToBeSynchronous()
{
// Do some work here
// ....
// Delete something in storage synchronously
DeleteSynchronous("pathGoesHere");
// Do other work here
// .....
}
希望这能有所帮助!
您可以从同步代码中调用任何异步方法,直到您需要等待它们,在这种情况下,它们也必须被标记为异步。
正如很多人在这里建议的那样,您可以在同步方法中对结果任务调用Wait()或Result,但最终会在该方法中进行阻塞调用,这在某种程度上违背了异步的目的。
如果你真的不能让你的方法异步,你不想锁定同步方法,那么你将不得不使用一个回调方法,把它作为参数传递给任务上的ContinueWith()方法。
var result = Task.Run(async () => await configManager.GetConfigurationAsync()).ConfigureAwait(false);
OpenIdConnectConfiguration config = result.GetAwaiter().GetResult();
或者用这个:
var result=result.GetAwaiter().GetResult().AccessToken
我不是100%确定,但我相信这篇博客中描述的技巧在许多情况下都适用:
因此,如果想直接调用这个传播逻辑,可以使用task.GetAwaiter(). getresult()。