Eng Mohamed Bassuny Ответов: 1

Как сделать фоновый рабочий в 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

спасибо за ваш намек Я сделал это так как вы говорите Я действительно ценю вашу помощь и никогда ее не забуду ...спасибо

1 Ответов

Рейтинг:
2

Graeme_Grant

Я написал статью о SQLite, которая показывает, как работать как с синхронными, так и с асинхронными методами, которые должны ответить на все ваши вопросы: Работа с SQLite в C# &VB[^]