我正在使用 .net核心(2.2)Web应用程序,并且具有一个控制器,该控制器负责进行按需数据同步处理。同样,我保留了一个按钮,单击该按钮会触发对服务的异步方法的调用。
在内部,此服务调用在操作以下进行处理
为了从服务内部与数据库进行交互,使用IOC /依赖注入(即通过构造函数)提供了 Db上下文对象。
为了确定问题原因,我使用多种方式进行服务方法调用:
在所有情况下,它都没有改变,仍然得到DbContext对象的 ObjectDisposedException 。
在更多地了解IOC的范围系统时,在我看来 一旦响应是作用域就被分配给db-context对象 提供给用户。
代码段,其中包含最少的行,如下所示:
AzureSearchIndexController.cs
public class AzureSearchIndexController : Controller
{
[HttpGet]
public IActionResult StartIndex()
{
_azureSearchDataSyncService.StartIndexingAsync(_siteId, _siteName);
}
}
AzureSearchDataSyncService.cs
public class AzureSearchDataSyncService : IAzureSearchDataSyncService
{
public AzureSearchDataSyncService(JobContext context,
ICacheHandler<AzureSearchDataSyncModel> cacheHandler,
AzureJobsTopicBus azureJobsTopicBus)
{
_context = context;
_cacheHandler = cacheHandler;
_azureJobsTopicBus = azureJobsTopicBus;
azureSearchDataSyncModel = new AzureSearchDataSyncModel();
}
public async Task StartIndexingAsync(int siteId, string siteName)
{
try
{
int fetchedData = 0;
int _batchSize = 10;
List<AzureJobMessageModel> azureJobMessages = new List<AzureJobMessageModel>();
var jobsToAdd_Update= GetData(siteId);
while (dataSyncModel.SyncStatus &&
fetchedData < jobsToAdd_Update.Count)
{
var batchData = jobsToAdd_Update.Skip(fetchedData)
.Take(_batchSize - azureJobMessages.Count)
.ToList();
if (batchData.Count <= 0)
continue;
azureJobMessages.AddRange(
PrepareAzureJobMessageModel(
PrepareAzureSearchIndexerModel(batchData),
EntityActionEnum.updated)
);
fetchedData += batchData.Count();
if (azureJobMessages.Count >= _batchSize)
{
//Method sending batch data
await _azureJobsTopicBus.SendMessageAsync(azureJobMessages);
dataSyncModel.ProcessedData += azureJobMessages.Count();
dataSyncModel.ProcessedBatches += 1;
azureJobMessages = new List<AzureJobMessageModel>();
}
}
}
catch(Exception ex)
{
throw ex;
}
}
}
所需结果:希望在单击按钮时采用异步模式的数据同步过程。
实际结果:
获取错误“ ObjectDisposedException-无法访问已处置的对象 (db-context)”
。有人对此有任何想法吗?
注意:-我不想使操作方法异步。我将在服务方法或包含CRUD操作逻辑的CRUD操作中使用此方法调用。我希望数据同步逻辑在后台运行,而不影响CRUD操作的响应时间。
答案 0 :(得分:1)
由于未等待服务调用,因此响应在服务之前完成,这将处理上下文。服务尝试访问上下文时导致错误。
使操作异步,然后等待服务
public class AzureSearchIndexController : Controller {
//...
[HttpGet]
public async Task<IActionResult> StartIndex() {
//...
await _azureSearchDataSyncService.StartIndexingAsync(_siteId, _siteName);
//...
}
}