当我的表由另一方更新时,dotnet核心中的db上下文仍然返回旧值,如何强制Db上下文刷新?
我已经完成了研究,但我只发现人们使用ReloadEF核心无法使用的方法来强制刷新上下文.
其他一些解决方案建议在使用后配置上下文,但是我得到错误说DB上下文是通过依赖注入创建的,我不应该搞砸它.
在创建报告时,我必须执行3个涉及相同上下文的分离实体的查询.因为它们非常沉重,所以我决定使用它.ToListAsync();来让它们并行运行,但令我惊讶的是,我得到了一个例外...
使用EF 6并行执行查询的正确方法是什么?我应该手动启动新任务吗?
编辑1
代码基本上是
using(var MyCtx = new MyCtx())
{
var r1 = MyCtx.E1.Where(bla bla bla).ToListAsync();
var r2 = MyCtx.E2.Where(ble ble ble).ToListAsync();
var r3 = MyCtx.E3.Where(ble ble ble).ToListAsync();
Task.WhenAll(r1,r2,r3);
DoSomething(r1.Result, r2.Result, r3.Result);
}
Run Code Online (Sandbox Code Playgroud) 我必须调用多个消耗时间的存储过程.理想情况下,这些程序必须在同一时间执行,但它会引发很多问题.
这是简化的代码:
private async void refresh_Controle(object sender, RoutedEventArgs e)
{
SqlParameter param1 = new SqlParameter("@devicename", DeviceName);
Task<int> mcResult = GenkaiBase.Database.ExecuteSqlCommandAsync("exec Refresh_McAfee @devicename", param1);
int Mc = await mcResult;
SqlParameter param2 = new SqlParameter("@devicename", DeviceName);
Task<int> dcaiResult = GenkaiBase.Database.ExecuteSqlCommandAsync("exec Refresh_DCAI @devicename", param2);
int Dc = await dcaiResult;
}
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
我尝试在异步方法中使用此代码同时调用这两个过程:
public async Task<bool> Refresh_Control(string devicename)
{
List<Task> Tlist = new List<Task>();
Console.WriteLine("Launch Refresh");
SqlParameter param1 = new SqlParameter("@devicename", devicename);
Task<int> mcResult = Genkai_db.Database.ExecuteSqlCommandAsync("exec Refresh_McAfee @devicename", param1);
SqlParameter param2 …Run Code Online (Sandbox Code Playgroud) c# asynchronous stored-procedures entity-framework async-await
刚才我已经发布了这个问题涉及到在客户端或服务应用异步等待.在继续讨论这个问题之前,请先阅读问题,因为它与问题紧密相关.
根据答案我已经测试了C#4.0(TPL)和C#5.0(Async - Await)的代码.我使用服务提供的方法的异步和同步版本来调用服务,并比较每种情况下使用的线程数.以下是我用于测试所用资源的代码:
主要方法
List<Task<string>> tasksList = new List<Task<string>>();
List<int> asyncThreads = new List<int>();
List<int> tplThreads = new List<int>();
Stopwatch watch = new Stopwatch();
watch.Start();
// Call the Async version of the method
for (int i = 0; i < 500; i++)
{
tasksList.Add(GetNameFromServiceAsync("Input" + i.ToString(), asyncThreads));
}
Task.WaitAll(tasksList.ToArray());
watch.Stop();
foreach (var item in asyncThreads.Distinct())
{
Console.WriteLine(item);
}
Console.WriteLine("(C# 5.0)Asynchrony Total Threads = " + asyncThreads.Distinct().Count());
Console.WriteLine(watch.ElapsedMilliseconds.ToString());
watch.Restart();
tasksList.Clear();
// Call the normal method
for (int i …Run Code Online (Sandbox Code Playgroud) 我有一个异步控制器动作方法,它在我的后端调用4个异步方法,从每个方法返回List.每个方法的对象列表都不同.即列表清单等
我这样做是这样的:
BizProvider bp = new BizProvider();
List<biz.Customer> custReturn = await bp.GetCustomerAsync();
List<biz.Account> acctReturn = await bp.GetAccountAsync();
...plus 2 more
List<object> returnArr = new List<object>();
returnArr.Add(custReturn);
returnArr.Add(acctReturn); ...plus 2 more
return JsonConvert.SerializeObject(returnArr);
Run Code Online (Sandbox Code Playgroud)
我应该使用Task.WhenAll多个任务吗?
微软的例子 https://msdn.microsoft.com/en-us/library/hh194874%28v=vs.110%29.aspx
所有任务都返回 List<int>
所以我使用了抽象类,并且我的所有列表对象类型都继承自此.并且我更改了业务对象提供程序的返回类型以返回抽象类型的列表,所以现在我可以这样做:
var tasks1 = new List<Task<List<Biz.AbstractClass>>>();
tasks1.Add(bp.GetCustomerAsAbstractAsync());
tasks1.Add(bp.GetAccountAsAbstractAsync());
...plus 2 more
Run Code Online (Sandbox Code Playgroud)
然后我调用var continuation = Task.WhenAll(tasks1);
这会执行它到达的下一行.Results然后停止执行???
foreach (var result in continuation.Result)
^ stops here
Run Code Online (Sandbox Code Playgroud)
我打电话
returnArrays.Add(result1);
return JsonConvert.SerializeObject(returnArrays);
Run Code Online (Sandbox Code Playgroud)
但这些永远不会受到打击......我不知道为什么.也许我不需要WhenAll,但我仍然好奇出了什么问题.也许我需要等待特定的函数,或以某种方式调用Action,就像在Microsoft链接中函数被内联调用一样.
Task.Run(async () => { x=x,etc...)
Run Code Online (Sandbox Code Playgroud)
编辑20150306 =>添加更多实施细节
CustMan …Run Code Online (Sandbox Code Playgroud) 我在ASP.Net MVC 5应用程序中遇到异步控制器问题.我正在使用Entity Framework 6 Code First方法.
我有一个方法
public async Task<ActionResult> Index()
{
using(var context = new MyDbContext())
{
var eventsTask = context.Events
.Where(e => e.Enable)
.ToListAsync();
var countTask = context.Users
.CountAsync();
await Task.WhenAll(eventsTask, countTask);
return View(new ViewModel()
{
Events = eventsTask.Result,
Count = countTask.Result
});
}
}
Run Code Online (Sandbox Code Playgroud)
我这里有两个异步方法.我通过MiniProfiler分别测量了它们.它们需要大约85毫秒.
但是在我的方法中,我使用Task.WhenAll()运行它们.我相信它以异步方式执行Db查询,并且两者都需要大约85-90毫秒.但它需要~170-180.所以我有异步方法同步运行(彼此跟随).
我认为这是因为背景.当我删除上下文查询并使用HttpClient调用许多api方法时,我有一个测试.它需要时间等于更长的时间(3 api调用,每个~500 ms.完全方法需要~600 ms).我相信可以异步执行EF方法.
有谁知道解决方案
我在使用任务/等待的 foreach 中有一些耗时的代码。它包括从数据库中提取数据、生成 html、将其发布到 API 以及将回复保存到数据库。
模型看起来像这样
List<label> labels = db.labels.ToList();
foreach (var x in list)
{
var myLabels = labels.Where(q => !db.filter.Where(y => x.userid ==y.userid))
.Select(y => y.ID)
.Contains(q.id))
//Render the HTML
//do some fast stuff with objects
List<response> res = await api.sendMessage(object); //POST
//put all the responses in the db
foreach (var r in res)
{
db.responses.add(r);
}
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
从时间上看,生成 Html 并将其发布到 API 似乎花费了大部分时间。
理想情况下,如果我可以生成下一个项目的 HTML,并等待帖子完成,然后再发布下一个项目,那就太好了。
也欢迎其他想法。人们会怎样做呢?
我首先想到Task在上面添加一个foreach并等待其完成然后再进行下一个 POST,但是我如何处理最后一个循环......感觉很混乱......
我有一个Web API方法,可以获得仪表板视图.
该方法调用大约24个不同的查询.每个查询执行大约需要60ms,我正在使用Glimpse进行配置.
我希望这样做,是异步运行它们,以避免一个接一个地调用每一个,从而使它成为60ms X 5方法调用.
我也是Async Await的新手,所以我的期望可能不正确.
这是我的Web API方法
[HttpGet]
[ExceptionHandling]
public async Task<DashboardResponse> GetDashboard()
{
return await DashboardResponse.GetDashboard();
}
Run Code Online (Sandbox Code Playgroud)
这是辅助方法
public static async Task<DashboardResponse> GetDashboard()
{
var resp = new DashboardResponse();
resp.MonthGlance = await GetMonthAtAGlance();
resp.MostRecentOrder = await GetMostRecentOrder();
resp.CreateAnOrder = await GetCreateAnOrder();
resp.RecentOrders = await GetRecentOrders();
resp.RecentNotifications = await GetRecentNotifications();
var messages = MessageResponse.GetMessages(new MessageFilters() { PageNumber = 1, PageSize = 10 }).Messages;
resp.RecentMessages.Messages = messages;
resp.OrderLineChart = GetOrderLineChart();
return resp;
}
Run Code Online (Sandbox Code Playgroud)
这是辅助方法内部调用的方法之一(其余方法设置非常相似)
public static async Task<MonthGlanceResp> …Run Code Online (Sandbox Code Playgroud) c# asynchronous entity-framework async-await asp.net-web-api
有人可以向我解释为什么我会为此收到设计/编译时错误。
我试图根据最后更新日期或创建日期获取每个表的最后一个 Guid。
var accountId = context.Account.OrderBy(x => x.LastUpdateDate).ThenBy(x=>x.LastUpdateDate).FirstOrDefaultAsync(x => x.UserAccount.ExternalId == _jwt.HomeAccountId).ExternalId;
var transactionLineId = context.TransactionLine.OrderBy(x => x.LastUpdateDate).ThenBy(x => x.LastUpdateDate).FirstOrDefaultAsync(x => x.Transaction.CreditAccount.UserAccount.ExternalId == _jwt.HomeAccountId).ExternalId;
var transactionId = context.Transaction.OrderBy(x => x.LastUpdateDate).ThenBy(x => x.LastUpdateDate).FirstOrDefaultAsync(x => x.CreditAccount.UserAccount.ExternalId == _jwt.HomeAccountId).ExternalId;
var budgetId = context.Budget.OrderBy(x => x.LastUpdateDate).ThenBy(x => x.LastUpdateDate).FirstOrDefaultAsync(x => x.UserAccount.ExternalId == _jwt.HomeAccountId).ExternalId;
var scheduleId = context.Schedule.OrderBy(x => x.LastUpdateDate).ThenBy(x => x.LastUpdateDate).FirstOrDefaultAsync(x => x.CreditAccount.UserAccount.ExternalId == _jwt.HomeAccountId).ExternalId;
Run Code Online (Sandbox Code Playgroud)
然后,等待每个响应并传递给一个方法。
var guids = new List<Guid> { await accountId, await transactionLineId, await transactionId, await budgetId, await scheduleId };
var …Run Code Online (Sandbox Code Playgroud) c# ×9
async-await ×5
asynchronous ×5
.net ×2
asp.net-mvc ×2
.net-core ×1
optimization ×1
performance ×1
sql-server ×1