C# 如果我不在父方法C中等待,则会出现巨大的性能差异#
我发现使用和不使用调用方提供的C# 如果我不在父方法C中等待,则会出现巨大的性能差异#,c#,entity-framework,async-await,C#,Entity Framework,Async Await,我发现使用和不使用调用方提供的wait之间存在巨大的性能差异。我觉得只有在返回时才有区别。也就是说,如果我使用wait,那么调用方方法应该在返回到下一个语句之前等待被调用方法的响应,否则调用方方法不需要等待响应,它可以继续执行进一步的语句 在我的例子中,如果在调用者方法中使用和不使用wait,则性能会有巨大的差异。也就是说,如果我不使用await,那么它将继续在调用方中执行下一条语句而不等待,但是它比在调用方中使用await要快得多 另外,我是否正确使用async&Wait 代码
wait
之间存在巨大的性能差异。我觉得只有在返回时才有区别。也就是说,如果我使用wait
,那么调用方方法应该在返回到下一个语句之前等待被调用方法的响应,否则调用方方法不需要等待响应,它可以继续执行进一步的语句
在我的例子中,如果在调用者方法中使用和不使用wait
,则性能会有巨大的差异。也就是说,如果我不使用await
,那么它将继续在调用方中执行下一条语句而不等待,但是它比在调用方中使用await
要快得多
另外,我是否正确使用async&Wait
代码
List<UserViewModel> _ListUser = new List<UserViewModel>();
public XmlElement CreateUpdateUser(Stream input)
{
Main(_ListUser, HttpContext.Current); // using await here makes performance slower and without await it's faster but it returns to the next statement immediately thats the problem.
return FormatResponse("S", "Record(s) created successfully.");
}
public async Task Main(List<UserViewModel> _ListUser, HttpContext current)
{
try
{
WriteToLog("Import Users - Start", 0, DateTime.Now);
UserViewModel _objSiteFileUserSettings = await FillupSiteFileSettings(new UserViewModel());
List<Branch> _branchCollection = await db.Branches.ToListAsync();
List<UserType> _usertypeCollection = await db.UserTypes.ToListAsync();
List<UserStatu> _userstatusCollection = await db.UserStatus.ToListAsync();
List<UserDept> _userdeptCollection = await db.UserDepts.ToListAsync();
List<UserLocation> _userlocationCollection = await db.UserLocations.ToListAsync();
HttpContext.Current = current;
//var tasks = new List<Task>();
foreach (var x in _ListUser)
Update1Record(x, _objSiteFileUserSettings, _branchCollection, _usertypeCollection, _userstatusCollection, _userdeptCollection, _userlocationCollection);
WriteToLog("Import Users - End", 0, DateTime.Now);
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
public string Update1Record(UserViewModel objUser, UserViewModel _objSiteFileUserSettings, List<Branch> _Lbranch, List<UserType> _Lusertype, List<UserStatu> _Luserstatus, List<UserDept> _Luserdept, List<UserLocation> _Luserlocation)
{
objUser.BranchSiteFile = _objSiteFileUserSettings.BranchSiteFile;
objUser.UsrTypeSiteFile = _objSiteFileUserSettings.UsrTypeSiteFile;
objUser.UsrStatSiteFile = _objSiteFileUserSettings.UsrStatSiteFile;
objUser.BranchId = objUser.Branch != null ? CheckBranch(objUser.Branch, _Lbranch) : null;
objUser.UserDeptId = objUser.UserDept != null ? CheckDept(objUser.UserDept, _Luserdept) : null;
objUser.UserLocationId = objUser.UserLocation != null ? CheckLocation(objUser.UserLocation, _Luserlocation) : null;
objUser.UserStatusId = objUser.UserStatus != null ? CheckStatus(objUser.UserStatus, _Luserstatus) : null;
objUser.UserTypeId = objUser.UserType != null ? CheckType(objUser.UserType, _Lusertype) : 0;
objUser._iEmail = _objSiteFileUserSettings._iEmail;
objUser._iSMS = _objSiteFileUserSettings._iSMS;
using (var VibrantDbContext = new VIBRANT())
using (var AuditDb = new VibrantAuditEntities())
using (var VibrantTransaction = VibrantDbContext.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
using (var AuditTransaction = AuditDb.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
try
{
VibrantDbContext.Configuration.AutoDetectChangesEnabled = false;
objUser.RecordTimeStamp = DateTime.Now;
var _ObjUserItem = FillupDateTimeValues(objUser);
ImportToDB(_ObjUserItem, 0, VibrantDbContext, AuditDb);
BuildImportLog(objUser, VibrantDbContext, AuditDb);
VibrantDbContext.SaveChanges();
AuditDb.SaveChanges();
VibrantTransaction.Commit();
AuditTransaction.Commit();
}
catch (Exception ex)
{
VibrantTransaction.Rollback();
AuditTransaction.Rollback();
throw new Exception(ex.ToString());
}
}
return "S";
}
public XmlElement FormatResponse(string Status, string Message)
{
XmlDocument xmlDoc = new XmlDocument();
XmlNode response = xmlDoc.CreateElement("Response");
xmlDoc.AppendChild(response);
XmlNode statusNode = xmlDoc.CreateElement("Status");
statusNode.InnerText = Status;
response.AppendChild(statusNode);
XmlNode MessageNode = xmlDoc.CreateElement("Message");
MessageNode.InnerText = Message;
response.AppendChild(MessageNode);
return xmlDoc.DocumentElement;
}
List\u ListUser=new List();
公共XmlElement CreateUpdateUser(流输入)
{
Main(_ListUser,HttpContext.Current);//在此处使用wait会降低性能,而不使用wait则会加快性能,但它会立即返回到下一条语句,这就是问题所在。
返回FormatResponse(“已成功创建记录”);
}
公共异步任务主(列表_ListUser,HttpContext当前)
{
尝试
{
WriteLog(“导入用户-开始”,0,DateTime.Now);
UserViewModel\u objSiteFileUserSettings=等待FillupSiteFileSettings(新的UserViewModel());
List _branchCollection=wait db.branchs.toListSync();
List _usertypeCollection=wait db.UserTypes.toListSync();
List _userstatusCollection=wait db.UserStatus.toListSync();
List _userdeptCollection=wait db.UserDepts.tolistSync();
List_userlocationCollection=await db.UserLocations.toListSync();
HttpContext.Current=Current;
//var tasks=新列表();
foreach(var x in_ListUser)
更新记录(x、_objSiteFileUserSettings、_branchCollection、_usertypeCollection、_userstatusCollection、_userdeptCollection、_userlocationCollection);
WriteToLog(“导入用户-结束”,0,DateTime.Now);
}
捕获(例外情况除外)
{
抛出新异常(例如ToString());
}
}
公共字符串更新记录(UserViewModel对象朱瑟、UserViewModel对象朱斯特文件用户设置、列表分支、列表Lusertype、列表Luserstatus、列表Luserdept、列表Luserlocation)
{
objUser.BranchSiteFile=_objSiteFileUserSettings.BranchSiteFile;
objUser.UsrTypeSiteFile=\u objSiteFileUserSettings.UsrTypeSiteFile;
objUser.UsrStatSiteFile=\u objSiteFileUserSettings.UsrStatSiteFile;
objUser.BranchId=objUser.Branch!=null?检查分支(objUser.Branch,_Lbranch):null;
objUser.UserDeptId=objUser.UserDept!=null?检查部门(objUser.UserDept,_Luserdept):null;
objUser.UserLocationId=objUser.UserLocation!=null?检查位置(objUser.UserLocation,_Luserlocation):null;
objUser.UserStatusId=objUser.UserStatus!=null?检查状态(objUser.UserStatus,_Luserstatus):null;
objUser.UserTypeId=objUser.UserType!=null?检查类型(objUser.UserType,_Lusertype):0;
objUser.\u iEmail=\u objSiteFileUserSettings.\u iEmail;
objUser.\u iSMS=\u objSiteFileUserSettings.\u iSMS;
使用(var VibrantDbContext=new VIBRANT())
使用(var AuditDb=new vibrantaudities())
使用(var VibrantTransaction=VibrantDbContext.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
使用(var AuditTransaction=AuditDb.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
尝试
{
VibrantDbContext.Configuration.AutoDetectChangesEnabled=false;
objUser.RecordTimeStamp=DateTime.Now;
var _ObjUserItem=FillupDateTimeValues(objUser);
ImportToDB(_ObjUserItem,0,VibrantDbContext,AuditDb);
BuildImportLog(objUser、VibrantDbContext、AuditDb);
VibrantDbContext.SaveChanges();
SaveChanges();
VibrantTransaction.Commit();
AuditTransaction.Commit();
}
捕获(例外情况除外)
{
VibrantTransaction.Rollback();
AuditTransaction.Rollback();
抛出新异常(例如ToString());
}
}
返回“S”;
}
公共XmlElement FormatResponse(字符串状态、字符串消息)
{
XmlDocument xmlDoc=新的XmlDocument();
XmlNode response=xmlDoc.CreateElement(“响应”);
xmlDoc.AppendChild(响应);
XmlNode statusNode=xmlDoc.CreateElement(“状态”);
statusNode.InnerText=状态;
response.AppendChild(statusNode);
XmlNode MessageNode=xmlDoc.CreateElement(“消息”);
MessageNode.InnerText=消息;
AppendChild(MessageNode);
返回xmlDoc.DocumentElement;
}
不,我想说您还没有掌握什么是async/await,以及何时使用它们。您应该阅读wait/async和Task,以完全理解实现,最重要的是了解使用此结构的原因。关于异步代码的常见误解是它使代码更快。这通常是不准确的。它实际上使特定的代码稍微慢一点,但是它使代码更具响应性,并允许您轻松地利用服务器的处理能力
从最简单的意义上讲,您编写或调用的代码通常需要等待一些东西。这可以用于I/O,如磁盘访问、数据库或其他通信。它还必须等待计算、代码完成一些需要花费大量时间才能完成的工作。如果您有几个这样的任务,那么平均需要
var result1 = DoSomething1(); //5 seconds.
var result2 = DoSomething2(); //5 seconds.
var result3 = DoSomething3(); //5 seconds.
var total = result1 + result2 + result3; // executes after 15 seconds.
var result1 = DoSomething1();
var result2 = DoSomething2();
var result3 = DoSomething3();
int total = result1 + result2 + result3; // ERROR! result1,2,3 are Taxk<int> representing they are a handle to executing code.
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
catch (Exception ex)
{
VibrantTransaction.Rollback();
AuditTransaction.Rollback();
throw;
}