我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
我有一个公共异步无效Foo()方法,我想从同步方法调用。到目前为止,我从MSDN文档中看到的都是通过异步方法调用异步方法,但我的整个程序并不是用异步方法构建的。
这可能吗?
下面是一个从异步方法调用这些方法的例子: 演练:使用Async和Await访问Web (c#和Visual Basic)
现在我正在研究从sync方法调用这些async方法。
当前回答
var result = Task.Run(async () => await configManager.GetConfigurationAsync()).ConfigureAwait(false);
OpenIdConnectConfiguration config = result.GetAwaiter().GetResult();
或者用这个:
var result=result.GetAwaiter().GetResult().AccessToken
其他回答
您可以从同步代码中调用任何异步方法,直到您需要等待它们,在这种情况下,它们也必须被标记为异步。
正如很多人在这里建议的那样,您可以在同步方法中对结果任务调用Wait()或Result,但最终会在该方法中进行阻塞调用,这在某种程度上违背了异步的目的。
如果你真的不能让你的方法异步,你不想锁定同步方法,那么你将不得不使用一个回调方法,把它作为参数传递给任务上的ContinueWith()方法。
斯蒂芬·克利里的回答;
这种方法应该不会导致死锁(假设 ProblemMethodAsync不发送更新到UI线程或任何东西 像这样)。它假设可以在对象上调用ProblemMethodAsync 线程池线程,这并不总是这样。
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
这就是方法;
线程池攻击与阻塞攻击类似的方法是 将异步工作卸载到线程池,然后阻塞 产生的任务。使用此黑客的代码看起来像下面的代码 如图7所示。 图7线程池攻击的代码 c#
public sealed class WebDataService : IDataService
{
public string Get(int id)
{
return Task.Run(() => GetAsync(id)).GetAwaiter().GetResult();
}
public async Task<string> GetAsync(int id)
{
using (var client = new WebClient())
return await client.DownloadStringTaskAsync(
"https://www.example.com/api/values/" + id);
}
}
Task的调用。Run在线程池上执行异步方法 线程。在这里,它将在没有上下文的情况下运行,从而避免 死锁。这种方法的一个问题是异步性 方法不能依赖于在特定上下文中执行。所以,它 不能使用UI元素或ASP。净HttpContext.Current。
这些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
// .....
}
希望这能有所帮助!
如果你想运行它同步
MethodAsync().RunSynchronously()
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方法。最大的区别是逻辑流没有中断,这使得读写更容易。