Я борюсь с проблемой использования асинхронного метода EntityFrmework 6.2 в приложении winform.Мы используем пользовательский класс для управления синхронизацией или асинхронным доступом EntityFrmework на основе одной настройки активности.Когда мы используем доступ к синхронизации все работает нормально.Когда мы используем асинхронный вызов, мы сталкиваемся с этой проблемой: вторая операция началась в этом контексте до завершения предыдущей асинхронной операции.Используйте 'await', чтобы убедиться, что все асинхронные операции завершены, прежде чем вызывать другой метод в этом контексте.Любые члены экземпляра не гарантируют поточно-ориентированность.Мы уже прочитали много постов по этой проблеме, но ни один из них не мог помочь нам решить нашу проблему.
Мы знаем, что проблема связана с вызовом асинхронного метода из синхронизированного, к сожалению, мы не смогли преобразовать вызовметод от синхронизации до асинхронности.Мы извлекли из нашего проекта два метода, чтобы продемонстрировать описанное поведение
public void AddLoadingRequest(Func<Task> fnAsync, Action fnSync, Action bsa)
{
try
{
Task task = Task.Run(async () => await DoDataSource(fnAsync, fnSync, bsa));
_lstTask.Add(task);
if (task.IsFaulted)
throw task.Exception;
}
catch (Exception ex)
{
MessageBox.Show($"Error {ex.Message}");
}
}
protected async Task DoDataSource(Func<Task> fnAsync, Action fnSync, Action bsa)
{
try
{
if (_bLoadingFKTableAsync == true)
await fnAsync();
else
fnSync();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Loading Error");
throw;
}
}
Вызов метода:
private void btnTest_Click(object sender, EventArgs e)
{
NWContext wContext = new NWContext();
Customers cust = wContext.Customers.FirstOrDefault(w => w.CustomerID == "RATTC");
BindingSource bsCustomer = new BindingSource();
BindingSource bsOrders = new BindingSource();
BindingSource bsCustomerDemographics = new BindingSource();
bsCustomer.DataSource = cust;
_bLoadingFKTableAsync = true;
AddLoadingRequest(
() => wContext.Entry(cust).Collection(typeof(Orders).Name).LoadAsync(),
() => wContext.Entry(cust).Collection(typeof(Orders).Name).Load(),
() =>
{
bsOrders.SuspendBinding();
bsOrders.DataSource = cust.Orders;
bsOrders.ResumeBinding();
});
AddLoadingRequest(
() => wContext.Entry(cust).Collection(typeof(CustomerDemographics).Name).LoadAsync(),
() => wContext.Entry(cust).Collection(typeof(CustomerDemographics).Name).Load(),
() =>
{
bsCustomerDemographics.SuspendBinding();
bsCustomerDemographics.DataSource = cust.CustomerDemographics;
bsCustomerDemographics.ResumeBinding();
});
}
Мы ожидаем, что EntityFramework загрузит две дочерние коллекции объекта в асинхронном режиме, в то время каку нас есть ошибка: вторая операция началась в этом контексте до завершения предыдущей асинхронной операции.Используйте 'await', чтобы убедиться, что все асинхронные операции завершены, прежде чем вызывать другой метод в этом контексте.Ни один из членов экземпляра не гарантированно является потокобезопасным.