Я подключаюсь к базе данных MS-ACCESS, используя Entity Framework и JetEntityFrameworkProvider.
У меня есть несколько длительных запросов, которые мне нужно выполнить, поэтому я запускаю их в потоке с помощью Task.Run.
Проблема, с которой я столкнулся, состоит в том, что, хотя я использую отдельный поток для запроса, и он использует свое собственное соединение и контекст, который не используется ни с кем другим, все остальные запросы в базе данных должны ждать, пока сложный запрос завершен.
Ниже приведен минимальный воспроизводимый пример, который я привел. Это конструктор для модели представления.
Public Sub New(mainViewModel As MainViewModel, mainItem As Product)
_mainViewModel = mainViewModel
Me.MainItem = mainItem
' This line actually changes the behavior of the program
' because the view data-binds to the Supplier.
' Reading it here forces EF to load it before starting
' the complex query below.
Dim n = mainItem.Supplier.Name
Task.Run(
Sub()
Dim conn = New JetConnection($"Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\Users.<DATAPATH>.mdb;")
Dim context = New MyContext(conn)
Dim query = <Some complex LINQ query>
MessageBox.Show($"Query count: {query.Count}.")
End Sub)
End Sub
Итак, это представление будет отображаться просто отлично. Но если я вернусь на страницу со списком продуктов, то ни один продукт не будет отображаться до тех пор, пока не будет выполнен вышеуказанный запрос.
Если я закомментирую чтение имени поставщика, то это представление будет нормально работать в первый раз, но все последующие раза само представление вообще не будет отображаться, пока запрос не будет завершен.
Кроме того, ToListAsync
, похоже, не работает. Похоже, он просто выполняется синхронно.
Мои вопросы:
- Что происходит? Почему запросы в одном потоке, использующие соединение, блокируют запросы в другом потоке, используя другое соединение?
- Как исправить или обойти эту проблему, чтобы долго выполняющиеся запросы могли выполняться без блокировки пользовательского интерфейса или других запросов.