Цикл foreach С# неожиданно пропускает некоторые строки

Кажется, это серьезная и подозрительная проблема. У меня есть простой цикл for-each, который перебирает строки таблицы данных. Мой код работал нормально почти год, вдруг эта проблема появилась месяц назад.

Я выполнил ведение журнала на основе текстового файла и заметил, что цикл for-each пропускает некоторые строки без каких-либо исключений в коде. У меня есть журнал в самой первой строке, когда начинается цикл, который также не работает для пропущенных элементов.

ниже мой код:

foreach (DataRow item in tblItemsToIssue.Rows)
        {
            Logger.LogInfo(string.Format("Start processing item = {0}", item["Item_Id"].ToString()));

            Dept_Item_BatchWise dibw = new Dept_Item_BatchWise();
            KeyValueCollection kvd = new KeyValueCollection();
            kvd.Add("Item_Id", Convert.ToInt32(item["Item_Id"]));
            kvd.Add("Department_Id", Convert.ToInt32(SessionObject.Get("User_Department_Id").ToString()));
            DataTable dt = dibw.GetFiltered_Table(kvd, true, "Expiry_Date", true);

            if (dt.Rows.Count > 0)
            {

                Logger.LogInfo("Batches found");

                //Check if available batches have enough quantity to issue
                int BatchesQuantitySum = 0;
                foreach (DataRow bItem in dt.Rows)
                {
                    BatchesQuantitySum += Convert.ToInt32(bItem["Quantity"]);
                }

                int QuantityNeedToIssue = Convert.ToInt32(item["Issue_Quantity"]);

                if (BatchesQuantitySum >= QuantityNeedToIssue)
                {
                    string documentDetailId = Convert.ToString(itemsDetailPharmacyIssuanceIds.GetByIndex(itemsDetailPharmacyIssuanceIds.IndexOfKey(item["Item_Id"])));

                    int QuantityInBatch = Convert.ToInt32(dt.Rows[0]["Quantity"]);

                    if (QuantityNeedToIssue > QuantityInBatch)
                    {
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            if (QuantityNeedToIssue > 0)
                            {
                                int batchQty = Convert.ToInt32(dt.Rows[i]["Quantity"]);
                                if (batchQty <= 0) //skip current batch coz it has 0 quantity
                                    continue;

                                int iQty = 0;

                                if (QuantityNeedToIssue <= batchQty)
                                {
                                    iQty = QuantityNeedToIssue;
                                    QuantityNeedToIssue -= iQty;
                                }
                                else
                                {
                                    iQty = batchQty;
                                    QuantityNeedToIssue -= iQty;
                                }

                                //Item Transaction Made
                                Dept_Item_Transaction dti = new Dept_Item_Transaction();
                                KeyValueCollection kv = new KeyValueCollection();
                                kv.Add("Document_Id", documentId);
                                kv.Add("Document_No", documentNo);
                                kv.Add("Document_Date", documentDate);
                                kv.Add("Document_Detail_Id", documentDetailId);
                                kv.Add("Item_Id", item["Item_Id"].ToString());
                                kv.Add("Unit_Id", item["Unit_Id"].ToString());
                                kv.Add("In_Out", "O");
                                kv.Add("Active", "Y");
                                kv.Add("Department_Id", Convert.ToInt32(SessionObject.Get("User_Department_Id").ToString()));
                                kv.Add("Unit_Price", item["Unit_Price"].ToString());
                                kv.Add("Employee_Id", SessionObject.Get("User_Employee_Id"));
                                kv.Add("Quantity", iQty);
                                if (DBNull.Value != dt.Rows[i]["Expiry_Date"] && !string.IsNullOrEmpty(dt.Rows[i]["Expiry_Date"].ToString()))
                                {
                                    DateTime t;
                                    DateTime.TryParse(dt.Rows[i]["Expiry_Date"].ToString(), out t);

                                    if (t != DateTime.MinValue)
                                        kv.Add("Expiry_Date", dt.Rows[i]["Expiry_Date"].ToString());
                                }
                                if (DBNull.Value != dt.Rows[i]["Batch_No"])
                                    kv.Add("Batch_No", dt.Rows[i]["Batch_No"].ToString());

                                dti.PerformTransaction(DocumentType.Issuance, kv);

                                Logger.LogInfo(string.Format("Issuance from Batch: {0}", dt.Rows[i]["Batch_No"].ToString()));
                            }
                            else
                            {
                                Logger.LogInfo("Multi batch issuance done.");
                                return;
                            }
                        }
                    }
                    else
                    {
                        //Item Transaction Made
                        Dept_Item_Transaction dti = new Dept_Item_Transaction();
                        KeyValueCollection kv = new KeyValueCollection();
                        kv.Add("Document_Id", documentId);
                        kv.Add("Document_No", documentNo);
                        kv.Add("Document_Date", documentDate);
                        kv.Add("Document_Detail_Id", documentDetailId);
                        kv.Add("Item_Id", item["Item_Id"].ToString());
                        kv.Add("Unit_Id", item["Unit_Id"].ToString());
                        kv.Add("In_Out", "O");
                        kv.Add("Active", "Y");
                        kv.Add("Department_Id", Convert.ToInt32(SessionObject.Get("User_Department_Id").ToString()));
                        kv.Add("Unit_Price", item["Unit_Price"].ToString());
                        kv.Add("Employee_Id", SessionObject.Get("User_Employee_Id"));
                        if (DBNull.Value != dt.Rows[0]["Expiry_Date"] && !string.IsNullOrEmpty(dt.Rows[0]["Expiry_Date"].ToString()))
                        {
                            DateTime t;
                            DateTime.TryParse(dt.Rows[0]["Expiry_Date"].ToString(), out t);

                            if (t != DateTime.MinValue)
                                kv.Add("Expiry_Date", dt.Rows[0]["Expiry_Date"].ToString());
                        }
                        if (DBNull.Value != dt.Rows[0]["Batch_No"])
                            kv.Add("Batch_No", dt.Rows[0]["Batch_No"].ToString());
                        kv.Add("Quantity", QuantityNeedToIssue);
                        dti.PerformTransaction(DocumentType.Issuance, kv);

                        Logger.LogInfo("Single Batch Issuance");
                    }
                }
                else
                {
                    Logger.LogInfo("Not available enoungh in stock : Process Terminate");

                    string error = string.Format("Internal error: Item Id '{0}' has not available enough in stock to issue.", item["Item_Id"].ToString());
                    throw new Exception(error);
                }
            }
            else
            {
                int QuantityNeedToIssue = Convert.ToInt32(item["Issue_Quantity"]);

                if (QuantityNeedToIssue > 0)
                {
                    Logger.LogInfo("No batches found : Process Terminate");

                    string error = string.Format("Internal error: Item Id '{0}' is missing from table Dept_Item_Batchwise.", item["Item_Id"].ToString());
                    throw new Exception(error);
                }
                else
                {
                    Logger.LogInfo("Item Skip: Issue quantity is 0");
                }
            }
        }

ЖУРНАЛ:

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Before save document total items count = 20

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
After save document total items count = 20

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Before save transaction total items count = 20

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 356

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 397

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1281

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 579

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 3195

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1886

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1845

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1080

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 3385

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 2702

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1453

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Single Batch Issuance

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Start processing item = 1448

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Batches found

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Issuance from Batch: 144

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Multi batch issuance done.

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
After save transaction total items count = 20

===== INFO ===== 26 Jun 2015 - 00:34:34 ===== Kacho Nisar (23) ===== IP:10.10.10.67 =====
Transaction committed

person Basit Ali    schedule 26.06.2015    source источник
comment
Звучит как проблема с блокировкой параллелизма, но не уверен, почему это произойдет внезапно. Что-то еще изменилось на уровне базы данных?   -  person Endareth    schedule 26.06.2015
comment
Кто изменяет tblItemsToIssue и когда? Есть ли шанс, что все транзакции в вашем цикле вызовут изменение этой таблицы?   -  person DrKoch    schedule 26.06.2015
comment
@DrKoch blItemsToIssue — это таблица в памяти, которая не будет обновляться в цикле. Я повторяю его и выполняю транзакцию базы данных.   -  person Basit Ali    schedule 26.06.2015
comment
В таком случае я бы сказал: Этого не может быть (ТМ). Не могли бы вы показать фрагмент вашего файла журнала, в котором подробно описана проблема?   -  person DrKoch    schedule 26.06.2015
comment
@DrKoch Пожалуйста, просмотрите мой журнал   -  person Basit Ali    schedule 26.06.2015
comment
Вы используете foreach в одной таблице, но затем регистрируете при повторении в другой таблице, загруженной с использованием данных из первой, аналогично левому соединению. Скорее всего для некоторых строк нет данных в соединяемой таблице. Невозможно помочь, не зная, что это за данные   -  person Panagiotis Kanavos    schedule 26.06.2015
comment
@DrKoch Я нашел проблему на самом деле здесь ‹code› if (QuantityNeedToIssue › QuantityInBatch) { .... } else { Logger.LogInfo(Выполнение нескольких пакетов.); возвращаться; } ‹/code› Я возвращаюсь сюда из функции, которая вызвала проблемы. Спасибо за помощь   -  person Basit Ali    schedule 26.06.2015


Ответы (1)


Возможное решение:

Скопируйте tblItemsToIssue в локальную (в памяти) таблицу непосредственно перед foreach.

person DrKoch    schedule 26.06.2015
comment
tblItemsToIssue — это таблица в памяти. - person Basit Ali; 26.06.2015