C# 在同步方法中使用异步图形API
我对这个不同步的世界还不熟悉,所以请接受我的知识 目前,;我们正在致力于实现Graph API以获取邮件文件夹、消息等交换数据。由于Graph API遵循APM(异步编程模型),我们遇到了“通过Asyc同步”的情况C# 在同步方法中使用异步图形API,c#,vb.net,multithreading,asynchronous,async-await,C#,Vb.net,Multithreading,Asynchronous,Async Await,我对这个不同步的世界还不熟悉,所以请接受我的知识 目前,;我们正在致力于实现Graph API以获取邮件文件夹、消息等交换数据。由于Graph API遵循APM(异步编程模型),我们遇到了“通过Asyc同步”的情况 _GraphServiceClient.Me.MailFolders.Request.GetAsync() 背景 List<MailFolder> mFolders = AsyncHelper.RunSync(async () => await GraphServ
_GraphServiceClient.Me.MailFolders.Request.GetAsync()
背景
List<MailFolder> mFolders = AsyncHelper.RunSync(async () => await GraphService.GetMailFolders(_GraphServiceClient));
让我把情况说出来,;邮件发送和不同邮件的相关代码位于我们的根类库中,它具有同步方法
这些方法将从同一库的不同类(即执行工作流步骤将发送邮件等)和ASP.NET Web应用程序、Windows窗体应用程序、控制台应用程序调用。现在,我们不能将邮件发送类的方法标记为Async,因为异步病毒会传播,并且我们不能使所有调用方都是异步的。将有大量代码需要重构
从过去几天开始,;我一直在阅读以下相关的洞察全文(Stephen Toub&Stephen Cleary)和一些这样的帖子
static class GraphService
{
public async static Task<List<MailFolder>> GetMailFolders(GraphServiceClient graphClient)
{
UserMailFoldersCollectionPage mFolders = await graphClient.Me.MailFolders.Request.GetAsync();
return mFolders.CurrentPage;
}
}
静态类图服务
{
公共异步静态任务GetMailFolders(GraphServiceClient graphClient)
{
UserMailFoldersCollectionPage mFolders=await graphClient.Me.MailFolders.Request.GetAsync();
返回mFolders.CurrentPage;
}
}
AsyncHelper
using System;
using System.Threading.Tasks;
internal static class AsyncHelper
{
// Private ReadOnly _myTaskFactory As TaskFactory = New TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.[Default])
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
// Dim cultureUi = CultureInfo.CurrentUICulture
// Dim culture = CultureInfo.CurrentCulture
// Return _myTaskFactory.StartNew(Function()
// Thread.CurrentThread.CurrentCulture = culture
// Thread.CurrentThread.CurrentUICulture = cultureUi
// Return func()
// End Function).Unwrap().GetAwaiter().GetResult()
return Task.Run(() =>
{
return func();
}).ConfigureAwait(false).GetAwaiter().GetResult();
}
public static void RunSync(Func<Task> func)
{
// Dim cultureUi = CultureInfo.CurrentUICulture
// Dim culture = CultureInfo.CurrentCulture
// _myTaskFactory.StartNew(Function()
// Thread.CurrentThread.CurrentCulture = culture
// Thread.CurrentThread.CurrentUICulture = cultureUi
// Return func()
// End Function).Unwrap().GetAwaiter().GetResult()
Task.Run(() =>
{
return func();
}).ConfigureAwait(false).GetAwaiter().GetResult();
}
}
使用系统;
使用System.Threading.Tasks;
内部静态类AsyncHelper
{
//Private ReadOnly _mytaskfactoryas TaskFactory=New TaskFactory(CancellationToken.None,TaskCreationOptions.None,TaskContinuationOptions.None,TaskScheduler.[默认])
公共静态TResult RunSync(Func Func)
{
//Dim cultureUi=CultureInfo.currentui culture
//Dim culture=CultureInfo.CurrentCulture
//Return\u myTaskFactory.StartNew(函数()
//Thread.CurrentThread.CurrentCulture=区域性
//Thread.CurrentThread.CurrentUICulture=cultureUi
//返回func()
//结束函数)。展开().GetWaiter().GetResult()
返回任务。运行(()=>
{
返回func();
}).ConfigureAwait(false).GetAwaiter().GetResult();
}
公共静态无效运行同步(Func Func)
{
//Dim cultureUi=CultureInfo.currentui culture
//Dim culture=CultureInfo.CurrentCulture
//_myTaskFactory.StartNew(函数()
//Thread.CurrentThread.CurrentCulture=区域性
//Thread.CurrentThread.CurrentUICulture=cultureUi
//返回func()
//结束函数)。展开().GetWaiter().GetResult()
Task.Run(()=>
{
返回func();
}).ConfigureAwait(false).GetAwaiter().GetResult();
}
}
根类库中的用法:
List<MailFolder> mFolders = AsyncHelper.RunSync(async () => await GraphService.GetMailFolders(_GraphServiceClient));
List mFolders=asynchHelper.RunSync(async()=>wait-GraphService.GetMailFolders(_-GraphServiceClient));
你能帮我解决这个建筑设计问题吗
- 当你没有选择的时候;“异步同步”和“异步同步”的最佳方法是什么李>
- 我认为“Async”和“Await”操作符不会导致创建额外的线程;那么异步是如何在同一线程中发生的。从技术上讲“Async”和“Await”如何在不创建新线程的情况下实现异步行为?事实上我对Task.Run和Async wait有点困惑
- 在如上所述的GraphService类中;它只返回当前页面数据。我们需要获取所有邮件文件夹,所以我想我们需要执行循环,然后再次执行相同的requurest来获取所有邮件文件夹,所以我认为;如果需要遵循该方法,我们可能需要遵循该类中的asynchHelper.RunSync选项
提前谢谢。请建议。对您的一些问题发表评论: 当你没有选择的时候;哪种方法是最好的选择 “异步同步”和“异步同步”
如果您想从异步转到同步,则需要等待,从而阻塞线程。我认为您的AsyncHelper是可以的,但我看不出您为什么要创建和等待其他任务。只需等待Func给出的任务。和
ConfigureAwait(false)
仅在与await
一起使用时有效。见下文
我认为“Async”和“Await”操作符不会导致额外的线程
被创造;那么异步是如何在同一线程中发生的。
从技术上讲“异步”和“等待”如何通过
我们正在创建一个新线程吗?事实上我有点困惑
Task.Run&异步等待
我相信文档中说,创建新线程是没有道理的。它可能会创建新线程。它还取决于上下文
在如上所述的GraphService类中;它只返回当前页面
数据。我们需要获取所有邮件文件夹,这样我想我们需要
执行循环,然后再次执行相同的Requirest以获取所有邮件
我想是这样的;我们可能需要遵循Asynchelper.RunSync选项
在那门课上,如果我们需要遵循这种方法
请注意,async/await并不意味着多任务。您可以看看TPL(任务并行库)
AsyncHelper:
internal static class AsyncHelper
{
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
return func().GetAwaiter().GetResult();
}
public static void RunSync(Func<Task> func)
{
func().Wait();
}
}
内部静态类AsyncHelper
{
公共静态TResult RunSync(Func Func)
{
return func().GetAwaiter().GetResult();
}
公共静态无效运行同步(Func Func)
{
func().Wait();
}
}
对一些问题的评论: