C# DbContext与任务
我们看到了一些难以重现的问题,这些问题似乎与SQL server以及我们如何与之通信有关,我正在调查我们是否将DBContext与任务错误结合使用 我们有一个信号中心,使用了我的许多不同的客户。当我们达到某一级别的客户机时,系统会减慢速度,最终停止工作 信号器与此示例类似,但有更多异步方法:C# DbContext与任务,c#,asp.net,entity-framework,signalr,C#,Asp.net,Entity Framework,Signalr,我们看到了一些难以重现的问题,这些问题似乎与SQL server以及我们如何与之通信有关,我正在调查我们是否将DBContext与任务错误结合使用 我们有一个信号中心,使用了我的许多不同的客户。当我们达到某一级别的客户机时,系统会减慢速度,最终停止工作 信号器与此示例类似,但有更多异步方法: namespace Test.Webservice.Hubs { public class ExampleHub : Hub<ExampleClientContract>, IExamp
namespace Test.Webservice.Hubs
{
public class ExampleHub : Hub<ExampleClientContract>, IExampleHub
{
private readonly ILogger _logger;
private readonly IExampleRepository _exampleRepo;
public ExampleHub(ILogger logger, IExampleRepository exampleRepo)
{
_logger = logger;
_exampleRepo = exampleRepo;
}
public async Task<IEnumerable<ExampleTopicState>> GetExampleStates(Guid operationId)
{
var examples = await _exampleRepo.GetExampleStatesAsync(operationId);
return examples.Select(ExampleTopicState.Create);
}
}
}
namespace Test.Webservice.Hubs
{
公共类ExampleHub:Hub,IEExampleHub
{
专用只读ILogger\u记录器;
私有只读IExampleRepository\u exampleRepo;
公共ExampleHub(ILogger记录器、IEExampleRepository exampleRepo)
{
_记录器=记录器;
_exampleRepo=exampleRepo;
}
公共异步任务GetExampleStates(Guid操作ID)
{
var examples=wait _exampleRepo.GetExampleStatesAsync(operationId);
返回examples.Select(ExampleTopicState.Create);
}
}
}
ExampleRepository看起来像这样,但又有更多的方法:
namespace Test.DataAccess.Repository
{
public class ExampleRepository : IExampleRepository
{
private readonly ILogger _logger;
private readonly ExampleContext _context;
private readonly IExampleRepositoryMapping _repositoryMapping;
public ExampleRepository(ILogger logger, IExampleRepositoryMapping repositoryMapping)
{
_repositoryMapping = repositoryMapping;
_logger = logger;
_context = new ExampleContext();
}
public async Task<IEnumerable<ExampleDto>> GetExampleStatesAsync(Guid operationId)
{
IEnumerable<Example> result = null;
await Task.Factory.StartNew(() =>
{
result = _context
.Examples.Where(c => c.OperationId.Equals(operationId))
.GroupBy(o => o.Type)
.SelectMany(p => p.GroupBy(q => q.Topic))
.Select(o => o.FirstOrDefault(
n => n.ExampleTimeUtc == o.Max(d => d.ExampleTimeUtc)));
});
return _repositoryMapping.Mapper.Map<IEnumerable<ExampleDto>>(result);
}
}
}
namespace Test.DataAccess.Repository
{
公共类ExampleRepository:IEExampleRepository
{
专用只读ILogger\u记录器;
私有只读示例上下文\u上下文;
私有只读IExampleRepositoryMapping\u repositoryMapping;
公共示例存储库(ILogger记录器,IExampleRepositoryMapping repositoryMapping)
{
_repositoryMapping=repositoryMapping;
_记录器=记录器;
_context=新示例context();
}
公共异步任务GetExampleStatesAsync(Guid操作ID)
{
IEnumerable结果=null;
等待任务。工厂。开始新建(()=>
{
结果=\u上下文
.Examples.Where(c=>c.OperationId.Equals(OperationId))
.GroupBy(o=>o.Type)
.SelectMany(p=>p.GroupBy(q=>q.Topic))
.选择(o=>o.FirstOrDefault(
n=>n.ExampleTimeUtc==o.Max(d=>d.ExampleTimeUtc));
});
返回_repositoryMapping.Mapper.Map(结果);
}
}
}
在wait Task.Factory.StartNew中使用DbContext是正确的,还是会导致问题?似乎说这可能有问题,但我不确定我是否完全理解
编辑:
Think id添加了一个示例,说明如何从一个客户端调用集线器:
var loadingTasks = _connectorMap.Select(o => (System.Action) ( () =>
{
var result = o.Proxy.Invoke<ExampleResult>(
"GetExampless",
_connectedOperations.Where(c => o.HubConnection.Url.StartsWith(c.ExampleWebService)).Select(s => s.UniqueId),
filter.TimeFilter.Start,
filter.TimeFilter.End,
filter.TopicFilter,
filter.SeverityLevelFilter,
currentPage, pageSize,
filter.IsGrouped).Result;
_results.Add(result);
}));
Parallel.ForEach(loadingTasks, lt => lt());
var-loadingTasks=\u connectorMap.Select(o=>(System.Action)(()=>
{
var result=o.Proxy.Invoke(
“GetExampless”,
_connectedOperations.Where(c=>o.HubConnection.Url.StartsWith(c.ExampleWebService))。选择(s=>s.UniqueId),
filter.TimeFilter.Start,
filter.TimeFilter.End,
filter.TopicFilter,
filter.SeverityLevelFilter,
当前页面,页面大小,
过滤结果;
_结果。添加(结果);
}));
Parallel.ForEach(加载任务,lt=>lt());
是否只需要选择异步
public async Task<IEnumerable<ExampleDto>> GetExampleStatesAsync(Guid operationId)
{
IEnumerable<Example> result = null;
var result = await _context
...
.SelectMany(...);
.Select(...)
.ToListAsync(); // Fetch from db.
});
return _repositoryMapping.Mapper.Map<IEnumerable<ExampleDto>>(result);
}
公共异步任务GetExampleStatesAsync(Guid操作ID)
{
IEnumerable结果=null;
var结果=等待上下文
...
.SelectMany(…);
.选择(…)
.ToListSync();//从数据库获取。
});
返回_repositoryMapping.Mapper.Map(结果);
}
有关完整示例,请访问。是否只需选择异步
public async Task<IEnumerable<ExampleDto>> GetExampleStatesAsync(Guid operationId)
{
IEnumerable<Example> result = null;
var result = await _context
...
.SelectMany(...);
.Select(...)
.ToListAsync(); // Fetch from db.
});
return _repositoryMapping.Mapper.Map<IEnumerable<ExampleDto>>(result);
}
公共异步任务GetExampleStatesAsync(Guid操作ID)
{
IEnumerable结果=null;
var结果=等待上下文
...
.SelectMany(…);
.选择(…)
.ToListSync();//从数据库获取。
});
返回_repositoryMapping.Mapper.Map(结果);
}
一个完整的例子可以在。IExampleRepository的生命周期是什么(即它是如何在DI中注册的)?
Task.Factory.StartNew
=“请在其他线程上为我运行此代码,我还有其他事情要做”-等待
-“在其他事情完成之前,我没有任何有用的工作要做”。你知道这些基本上是矛盾的吗?如果您当前的线程在某些方面不是特别的,只需在现有线程上运行代码即可。@Damien_the_unsiver这一点很好。这可能是我们看到的问题的原因吗?@devNull它是这样注册的:container.Register(Component.For().ImplementedBy().LifestyleTransient());IExampleRepository
(即如何在DI注册)的生命周期是什么?Task.Factory.StartNew
=“请在其他线程上为我运行此代码,我还有其他事情要做”-等待
-“在其他事情完成之前,我没有有用的工作要做”。你知道这些大多是相反的吗