Как сделать фоновый рабочий в C# для вставки данных в базу данных sqlite
Всем Привет
Прежде всего "Пожалуйста не судите меня я новичок в программировании"
я хочу добавить и обновить некоторые данные в базе данных, но форма всегда получалась Замерзать
поэтому я ищу, чтобы решить свою проблему, и я нашел Фоновый Работник
и я попытался реализовать шаги, которые я нашел в интернете, но это ничего не дало и не сработало по-райтовски, я думаю
Что мне нужно
1. Отключите некоторые компоненты в основной форме
2. отображение "загрузка панели" (имеет индикатор выполнения "Шатер"и ярлык и картинка), то добавление данных при отображении панели и прогрсс бар работать
Мое Изображение Панели Загрузки
3. после окончания работы включите некоторые компоненты в основной вид
если кто-то может помочь мне реализовать эту идею, я буду благодарен
Что я уже пробовал:
private void btnAddHoleInvoiceData_Click(object sender, EventArgs e) { switch (MessageBox.Show(this, "هل تريد بالتأكيد إدخال بيانات الفاتورة (" + it.TempInvoice_Id + ") \"لا يمكن التراجع عن العملية\" ؟", "تأكيد الإدخال", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { case DialogResult.Yes: #region To Do Befor Adding cmbBxCompanyName.Enabled = false; txtBxInvoiceDescription.Enabled = false; txtBxInvoiceNote.Enabled = false; btnAddNewInvoice.Enabled = false; btnDeleteTempInvoice.Enabled = false; txtBxInvoiceTaxRate.Enabled = false; txtBxInvoiceOther.Enabled = false; txtBxInvoiceDeposit.Enabled = false; cmbBxItems.Enabled = false; txtBxQuantity.Enabled = false; txtBxUnitPrice.Enabled = false; txtBxDiscount.Enabled = false; listView.Enabled = false; btnAddItem.Enabled = false; btnRemoveItem.Enabled = false; lblItemsTotalPrice.Enabled = false; lblInvoiceTotalPrice.Enabled = false; button5.Enabled = false; btnUpdateCustomerData.Enabled = false; btnCancel.Enabled = false; ControlBox = false; pnlLoding.Visible = true; pnlLoding.Refresh(); int milliseconds = 4000; Thread.Sleep(milliseconds); #endregion bgWorker.RunWorkerAsync(); #region To Do After Adding it.LastInvoice_Id = it.TempInvoice_Id; it.TempInvoice_Id = 0; int milliseconds2 = 4000; Thread.Sleep(milliseconds2); grpBxInvoiceData.Text = " Invoice Data "; foreach (ListViewItem eachItem in listView.Items) { listView.Items.Remove(eachItem); } lblItemsTotalPrice.Text = getItemsSum().ToString("0.00"); lblInvoiceTotalPrice.Text = getInvoiceTotalSum().ToString("0.00"); txtBxInvoiceDescription.Text = string.Empty; txtBxInvoiceNote.Text = string.Empty; txtBxInvoiceTaxRate.Text = "0.00"; txtBxInvoiceOther.Text = "0.00"; txtBxInvoiceDeposit.Text = "0.00"; cmbBxItems.SelectedIndex = 0; txtBxStoreQuantity.Refresh(); txtBxQuantity.Text = string.Empty; txtBxUnitPrice.Text = string.Empty; txtBxDiscount.Text = string.Empty; pnlLoding.Visible = false; cmbBxCompanyName.Enabled = true; txtBxInvoiceDescription.Enabled = true; txtBxInvoiceNote.Enabled = true; btnAddNewInvoice.Enabled = true; btnDeleteTempInvoice.Enabled = false; txtBxInvoiceTaxRate.Enabled = true; txtBxInvoiceOther.Enabled = true; txtBxInvoiceDeposit.Enabled = true; cmbBxItems.Enabled = false; txtBxQuantity.Enabled = false; txtBxUnitPrice.Enabled = false; txtBxDiscount.Enabled = false; listView.Enabled = false; btnAddItem.Enabled = false; btnRemoveItem.Enabled = false; lblItemsTotalPrice.Enabled = true; lblInvoiceTotalPrice.Enabled = true; button5.Enabled = true; btnUpdateCustomerData.Enabled = false; btnCancel.Enabled = true; ControlBox = true; #endregion break; case DialogResult.No: return; default: break; } }
Сделайте Работу "BackgroundWorker"
private void BgWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { int StoreQuantity = 0; //try //{ if (listView.Items.Count > 0) { dbConnection StartConn = new dbConnection(); SQLiteConnection MyConnetion = StartConn.GetConnection(); #region Update Invoice Data In Database SQLiteCommand Cm_1 = new SQLiteCommand("Update Invoices set Invoice_Description = @Invoice_Description, Invoice_TaxRate =@Invoice_TaxRate, Invoice_Other = @Invoice_Other, Invoice_Deposit = @Invoice_Deposit, Invoice_DetailTotal = @Invoice_DetailTotal, Invoice_InvoiceTotal = @Invoice_InvoiceTotal, Invoice_Note = @Invoice_Note where Invoice_Id = @Invoice_Id", MyConnetion); Cm_1.Parameters.Add("@Invoice_Id", it.TempInvoice_Id.ToString()); Cm_1.Parameters.Add("@Invoice_Description", txtBxInvoiceDescription.Text); Cm_1.Parameters.Add("@Invoice_TaxRate", txtBxInvoiceTaxRate.Text); Cm_1.Parameters.Add("@Invoice_Other", txtBxInvoiceOther.Text); Cm_1.Parameters.Add("@Invoice_Deposit", txtBxInvoiceDeposit.Text); Cm_1.Parameters.Add("@Invoice_DetailTotal", lblItemsTotalPrice.Text); Cm_1.Parameters.Add("@Invoice_InvoiceTotal", lblInvoiceTotalPrice.Text); Cm_1.Parameters.Add("@Invoice_Note", txtBxInvoiceNote.Text); MyConnetion.Open(); Cm_1.ExecuteNonQuery(); MyConnetion.Close(); #endregion #region Insert Invoice Items for (var i = 0; i < listView.Items.Count; i++) { SQLiteCommand Cm_2 = new SQLiteCommand("insert into InvoiceDetails (Invoice_Id,Item_Id,Item_Description,Item_NeededQuantity,Item_UnitPrice,Item_Discount,Item_Total) " + "values (@Invoice_Id,@Item_Id,@Item_Description,@Item_NeededQuantity,@Item_UnitPrice,@Item_Discount,@Item_Total)", MyConnetion); Cm_2.Parameters.Add("@Invoice_Id", it.TempInvoice_Id.ToString()); Cm_2.Parameters.Add("@Item_Id", listView.Items[i].SubItems[0].Text); Cm_2.Parameters.Add("@Item_Description", listView.Items[i].SubItems[1].Text); Cm_2.Parameters.Add("@Item_NeededQuantity", listView.Items[i].SubItems[2].Text); Cm_2.Parameters.Add("@Item_UnitPrice", listView.Items[i].SubItems[3].Text); Cm_2.Parameters.Add("@Item_Discount", listView.Items[i].SubItems[4].Text); Cm_2.Parameters.Add("@Item_Total", listView.Items[i].SubItems[5].Text); MyConnetion.Open(); Cm_2.ExecuteNonQuery(); MyConnetion.Close(); } #endregion #region Update Items Quantity In Database for (var i = 0; i < listView.Items.Count; i++) { SQLiteCommand Cm_3 = new SQLiteCommand(" select Item_StoreQuantity from Items where Item_Id = '" + listView.Items[i].SubItems[0].Text + "'", MyConnetion); MyConnetion.Open(); int count = Convert.ToInt32(Cm_3.ExecuteScalar()); SQLiteDataReader dr = Cm_3.ExecuteReader(); dr.Read(); if (count != 0) { StoreQuantity = Convert.ToInt32(dr["Item_StoreQuantity"]); MyConnetion.Close(); } else { } int updateStoreQuantity = StoreQuantity - Convert.ToInt32(listView.Items[i].SubItems[2].Text); SQLiteCommand Cm_4 = new SQLiteCommand("Update Items set Item_StoreQuantity = @Item_StoreQuantity where Item_Id = @Item_Id", MyConnetion); Cm_4.Parameters.Add("@Item_Id", listView.Items[i].SubItems[0].Text); Cm_4.Parameters.Add("@Item_StoreQuantity", updateStoreQuantity.ToString()); MyConnetion.Open(); Cm_4.ExecuteNonQuery(); MyConnetion.Close(); } #endregion } else { } }
Christian Graus
Вместо того чтобы публиковать 10000 строк, публикуйте бит, который делает то, о чем вы говорите. Вы знаете, как использовать ваш отладчик? Что значит "не работает" означает? Называется ли ваш фоновый код? Что он делает?
Eng Mohamed Bassuny
прости меня за это . я подумал, что будет лучше, если я поставлю эти два события, и я думаю, что поставлю именно то, о чем говорю
я должен посмотреть в базе данных
1. Обновление Счета-Фактуры
2. Вставка Элементов Счета-Фактуры
3. Обновление Количества Элементов В Базе Данных
но то, что я получил, - это обновление счета-фактуры только в базе данных
я позвонил backgroung >>>bgWorker.RunWorkerAsync();
это делает весь второй код, который я пишу >>> Do Work "BackgroundWorker"
это мой проект
https://drive.google.com/file/d/13W7OdFR9mR1qQzFdu3shuiYgy-CmJ2aY/view?usp=sharing
и я использую его потому что когда я помещаю весь этот код в кнопку он вешает пользовательский интерфейс
и я ищу какую-то помощь, и я обнаружил, что backgroungworker будет способом решить эту проблему
так что если вы поможете мне и скажете как это сделать я буду вам очень благодарен
Christian Graus
Кроме того, асинхронный метод должен быть вызван с ключевым словом await, которое требует сделать метод асинхронным
BillWoodruff
Начните с рассказа о том, что именно пошло не так в вашей первой попытке: какое было сообщение об ошибке; какие значения вы увидели, которые не ожидались или были ошибочными ?
Eng Mohamed Bassuny
я поставил фоновый рабочий, чтобы избежать сбоя пользовательского интерфейса, но когда я его использую, он ничего не делает, и индикатор выполнения висит
и я должен посмотреть в базе данных
1. Обновление Счета-Фактуры
2. Вставка Элементов Счета-Фактуры
3. Обновление Количества Элементов В Базе Данных
но то, что я получил, - это обновление счета-фактуры только в базе данных
я не получил никакого массажа ошибок или каких-либо исключений, поэтому я решил обратиться за помощью
это мой проект
https://drive.google.com/file/d/13W7OdFR9mR1qQzFdu3shuiYgy-CmJ2aY/view?usp=sharing
Graeme_Grant
Вам не нужно использовать BackgroundWorker, чтобы разблокировать пользовательский интерфейс. Модель асинхронного программирования задачи[^] используется в приведенном ниже решении, делает это для вас в гораздо более простом для реализации и чтения методе, чем то, что вы пытаетесь сделать.
Eng Mohamed Bassuny
я пытался понять и использовать Async / Await, но все равно пользовательский интерфейс зависает
частная асинхронного btnUpdateCustomerData_Click недействительным(объект отправителя, EventArgs в электронной)
{
//код до этого
ждите InserInvoice();
//код после
}
частная асинхронная задача InserInvoice()
{
//Весь Мой Код
}
Я получил это предупреждение
"Этот асинхронный метод не имеет операторов 'await' и будет работать синхронно. Рассмотрите возможность использования оператора 'await' для ожидания неблокирующих вызовов API или 'await Task.Run(...)' для выполнения работы с ЦП в фоновом потоке."
при всех введенных данных счета-фактуры, но пользовательский интерфейс все еще висит, а индикатор выполнения висит "не работает"
так что я думаю, что я что-то упустил вы можете мне помочь
Graeme_Grant
Вы делаете какие-нибудь асинхронные вызовы InserInvoice
метод?
Если да, то добавьте await xxxAsync(...).ConfigureAwait(false);
для звонков внутри InserInvoice
метод. Это гарантирует, что вызовы будут перемещены в другой поток.
еще один трюк, если есть также асинхронный код, заключается в вызове await Task.Yeild;
сразу же при входе InserInvoice
метод быстрого доступа к потоку пользовательского интерфейса.
Как и любые новые фреймворки, которые вы используете, всегда полезно сначала провести исследование и понять, что вы делаете.
Вот несколько ссылок, которые помогут вам понять, как работает асинхронность...ждите работ:
* Шаблоны асинхронного программирования | Microsoft Docs[^]
* C#: почему вы должны использовать ConfigureAwait(false) в коде вашей библиотеки[^]
* Асинхронные рекомендации для C# и Visual Basic - YouTube[^]
* Задача.Метод Выхода (Система.Нарезание резьбы.Задачи) | Microsoft Docs[^]
* c# - Когда я буду использовать Task.Выход()? - переполнение стека[^]
Richard Deeming
SQLiteCommand Cm_3 = new SQLiteCommand(" select Item_StoreQuantity from Items where Item_Id = '" + listView.Items[i].SubItems[0].Text + "'", MyConnetion);
Ваш код потенциально уязвим для SQL-инъекция[^]. НИКОГДА используйте конкатенацию строк для построения SQL-запроса. ВСЕГДА используйте параметризованный запрос.
Все, что вы хотели знать о SQL-инъекции (но боялись спросить) | Трой Хант[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? | Обмен Стеками Информационной Безопасности[^]
Шпаргалка по параметризации запросов | OWASP[^]
NB: Вы правильно использовали параметры для других команд; просто сделайте то же самое для этой команды.
Eng Mohamed Bassuny
спасибо за ваш намек Я сделал это так как вы говорите Я действительно ценю вашу помощь и никогда ее не забуду ...спасибо