Я использую ASP.MVC 5 и EF6. Моя цель - заполнить базу данных данными с другого сервера, а не блокировать пользовательский интерфейс.ASP.MVC EF6 базовый интерфейс блокировки заполнения
Заполнение базы данных занимает много времени, около 10-15 минут. И пользователь может работать с системой в это время. Теперь он очень сильно замерзает в течение нескольких минут. Таким образом, факт состоит в том, что пользователь загружает данные из базы и заполняет задачу загрузки данных в базу данных за один раз.
Я попытался поместить код заполнения базы данных в другие потоки, но это не помогло. Когда пользователь регистрируется в первый раз, он выполняет некоторые действия, которые запускают заполнение базы данных. После этого действия пользователь может делать что-либо еще, и интерфейс не должен блокироваться.
Когда пользователь пользуется системой, ему всегда нужно загрузить некоторые данные из моей базы данных. Например: когда пользователь видит какую-то страницу в течение 1 минуты, есть 10000 загруженных данных, на 2 минуты больше данных и т. Д.
public ActionResult SomeAction()
{
new Thread(async() =>
{
Thread.CurrentThread.IsBackground = true;
await ImportTask();
}).Start();
... (some code)
return View();
}
public async Task ImportTask()
{
for (var i = 0; i < 180; i++)
{
using (var context = new ApplicationDBContext())
{
// synchronized data download with some sided library
var data = GetSomeDataFromAnotherServer(i);
foreach (var dataPart in data)
{
var stat = context.Data
.FirstOrDefault(x =>
x.EnumProperty == dataPart.EnumProperty &&
x.LongProperty == dataPart.LongProperty &&
x.DateTimeProperty == dataPart.DateTimeProperty)
?? new DataType()
{
EnumProperty = dataPart.EnumProperty,
LongProperty = dataPart.LongProperty,
DateTimeProperty == dataPart.DateTimeProperty
};
... (some another stat filling)
context.Statistics.AddOrUpdate(stat);
}
await context.SaveChangesAsync();
}
}
}
И еще один вопрос: у меня есть возможность загружать данные примерно с 10 потоками за один раз. Как я могу изменить этот код, чтобы сделать это?
p.s. код может содержать некоторые опечатки здесь
Я не вижу способ использовать только 1 AppDBContext для всех операций. Проблема в том, что контекст может быть внезапно закрыт через 1-2 минуты с исключением. Мы избегаем этой проблемы с контекстом Owin, но она работает только для действий, а задача не является действием. – stationfuk
Восстановить контекст после n вставок или использовать 'System.Data.SqlClient.SqlBulkCopy'. Исключение после 1-2 минут у вас есть, вероятно, «OutOfMemoryException». См. [Самый быстрый способ вставки в инфраструктуру Entity Framework] (http: // stackoverflow.com/a/5942176/5246410) –
'SaveChanges' также должен быть внешним циклом, так что вы не получите вызов базы данных для каждого обновления элемента. –