我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
当前回答
public async Task<string> StartMyTask()
{
await Foo()
// code to execute once foo is done
}
static void Main()
{
var myTask = StartMyTask(); // call your method which will return control once it hits await
// now you can continue executing code here
string result = myTask.Result; // wait for the task to complete to continue
// use result
}
您将‘await’关键字读为“启动这个长时间运行的任务,然后将控制权返回给调用方法”。长时间运行的任务完成后,它将执行后面的代码。await之后的代码类似于过去的CallBack方法。最大的区别是逻辑流没有中断,这使得读写更容易。
其他回答
我不是100%确定,但我相信这篇博客中描述的技巧在许多情况下都适用:
因此,如果想直接调用这个传播逻辑,可以使用task.GetAwaiter(). getresult()。
添加一个解决方案,最终解决了我的问题,希望能节省别人的时间。
首先阅读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;
}
}
这是最简单的解决办法。我在网上的某个地方看到它,我不记得在哪里了,但我一直在成功地使用它。它不会死锁调用线程。
void SynchronousFunction()
{
Task.Run(Foo).Wait();
}
string SynchronousFunctionReturnsString()
{
return Task.Run(Foo).Result;
}
string SynchronousFunctionReturnsStringWithParam(int id)
{
return Task.Run(() => Foo(id)).Result;
}
public async Task<string> StartMyTask()
{
await Foo()
// code to execute once foo is done
}
static void Main()
{
var myTask = StartMyTask(); // call your method which will return control once it hits await
// now you can continue executing code here
string result = myTask.Result; // wait for the task to complete to continue
// use result
}
您将‘await’关键字读为“启动这个长时间运行的任务,然后将控制权返回给调用方法”。长时间运行的任务完成后,它将执行后面的代码。await之后的代码类似于过去的CallBack方法。最大的区别是逻辑流没有中断,这使得读写更容易。
var result = Task.Run(async () => await configManager.GetConfigurationAsync()).ConfigureAwait(false);
OpenIdConnectConfiguration config = result.GetAwaiter().GetResult();
或者用这个:
var result=result.GetAwaiter().GetResult().AccessToken