//проблема с многопоточностью //наверняка нужно создавать новый контекст для каждого потока //или опрашивать и сохранять данные локально с последующей выгрузкой в базу данных private void Connection(FavoriteConnect favConnect) { RemoteTask task = favConnect.task; List <string> commands = favConnect.commands; Favorite fav = favConnect.favorite; //данные для подключения к сетевому устройству ConnectionData data = new ConnectionData(); data.address = fav.Address; data.port = fav.Port; data.username = fav.Credential.Username; data.password = fav.Credential.Password; //по типу протоколу выбираем требуемое подключение string protocol = fav.Protocol.Name; Expect.Expect expect; switch (protocol) { case "Telnet": expect = new TelnetMintExpect(data); break; case "SSH": expect = new SshExpect(data); break; //по умолчанию для сетевых устройств протокол Telnet default: expect = new TelnetMintExpect(data); break; } //если объект expect успешно создан if (expect != null) { //выполняем список команд expect.ExecuteCommands(commands); string result = expect.GetResult(); bool success = expect.isSuccess; string error = expect.GetError(); //если успешно сохраняем конфигурацию устройства if (success) { Config config = new Config(); config.Current = result; config.Date = DateTime.Now; fav.Configs.Add(config); } //создаем отчет о проделанном задании Report report = new Report(); report.Date = DateTime.Now; report.Status = success; report.Info = error; report.Task = task; report.Favorite = fav; context.Reports.Add(report); context.SaveChanges(); } }
/* * The entity framework DbContext and ObjectContext classes are NOT thread-safe. So you should not use them over multiple threads. * Although it seems like you're only passing entities to other threads, it's easy to go wrong at this, when lazy loading is involved. * This means that under the covers the entity will callback to the context to get some more data. * So instead, I would advice to convert the list of entities to a list of special immutable data structures that only need the data that is needed for the calculation. * Those immutable structures should not have to call back into the context and should not be able to change. * When you do this, it will be safe to pass them on to other threads to do the calculation. */ private void LoadConfiguration(RemoteTask task) { ProgressInit(); try { foreach (Favorite fav in task.Favorites) { current++; ProgressStep(fav.Address); List <string> commands = new List <string>(); //проходим по списку команд, выявляем соответствие используемой команды и категории избранного foreach (Command command in task.Commands.OrderBy(c => c.Order)) { foreach (Category category in command.Categories) { if (fav.Category.CategoryName == category.CategoryName) { commands.Add(command.Name); } } } //устанавливаем соединение FavoriteConnect connect = new FavoriteConnect(); connect.commands = commands; connect.favorite = fav; connect.task = task; Connection(connect); } MessageBox.Show("Task is complete!", "Task Progress", MessageBoxButtons.OK, MessageBoxIcon.Information); ProgressFinish(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } }