La barra de progreso excede el valor máximo cuando se usa la operación ++ para incrementar el valor. En el siguiente código, tengo un conjunto de registros que tiene un tamaño de 6004 cuando llega al bucle, se las arregla para llegar a 6006 a pesar de que puse una declaración if para atrapar cuando alcanza el valor ++ para restablecer la barra de progreso a cero y también ocultar el panel.
invoiceRecord = (SageDataObject240.InvoiceRecord)_workSpace.CreateObject(Resources.InvoiceRecord);
pnlProgress.Visible = true;
progBarSelectInvoices.Value = 0;
progBarSelectInvoices.Maximum = invoiceRecord.Count;
List<EdiInvoice> selectedInvoices = new List<EdiInvoice>();
EdiInvoice invoice;
DateTime fromDate = chkEnableFromDatePicker.Checked ? dtpFrom.Value.Date : DateTime.MinValue;
DateTime toDate = chkEnableToDatePicker.Checked ? dtpTo.Value.Date : DateTime.MaxValue;
int invoiceCount = 0;
int progressCount = 0;
int progresbarValue = 0;
int maxCount = invoiceRecord.Count + 1;
while (invoiceRecord.MoveLast())
{
progresbarValue = progBarSelectInvoices.Value++;
bool isPosted = (SDOHelper.Read<sbyte>(invoiceRecord, Resources.POSTED_CODE) == 1);
if (isPosted)
{
int invoiceNo = SDOHelper.Read<int>(invoiceRecord, Resources.INVOICE_NUMBER);
string invoiceCustomerReference = SDOHelper.Read<string>(invoiceRecord, Resources.ACCOUNT_REF);
bool isValidCustomerReference = (invoiceCustomerReference == _selectedCustomer.Reference || _selectedCustomer.IncludeBranchInvoices && _selectedCustomer.BranchCodes.ContainsKey(invoiceCustomerReference));
sbyte invoiceTypeCode = SDOHelper.Read<sbyte>(invoiceRecord, Resources.INVOICE_TYPE_CODE);
bool isValidType = invoiceTypeCode >= 0 && invoiceTypeCode <= 5;
string notes1 = SDOHelper.Read<string>(invoiceRecord, "NOTES_1");
bool isExported = notes1.Length > 2 && notes1.Substring(0, 3).Equals("EDI", StringComparison.CurrentCultureIgnoreCase);
DateTime invoiceDate = SDOHelper.Read<DateTime>(invoiceRecord, "INVOICE_DATE");
bool isInDateRange = invoiceDate >= fromDate && invoiceDate <= toDate;
if (isValidCustomerReference && isValidType && (!isExported || chkIncludeAlreadyExportedInvoices.Checked) && isInDateRange)
{
invoice = new EdiInvoice();
invoice.Customer = string.Format("({0}), {1}", invoiceCustomerReference, SDOHelper.Read<string>(invoiceRecord, Resources.NAME));
invoice.InvoiceNumber = invoiceNo;
invoice.Date = SDOHelper.Read<DateTime>(invoiceRecord, "INVOICE_DATE").ToString("dd/MM/yyyy");
invoice.Type = GetInvoiceOrCredit(invoiceTypeCode);
invoice.DeliveryAddress = SDOHelper.Read<string>(invoiceRecord, Resources.DEL_ADDRESS_1);
invoice.Nett = SDOHelper.Read<double>(invoiceRecord, Resources.BASE_TOT_NET) + SDOHelper.Read<double>(invoiceRecord, Resources.BASE_CARR_NET);
invoice.Vat = SDOHelper.Read<double>(invoiceRecord, Resources.BASE_TOT_TAX) + SDOHelper.Read<double>(invoiceRecord, Resources.BASE_CARR_TAX);
selectedInvoices.Add(invoice);
}
}
invoiceCount = invoiceRecord.Count;
progressCount = progBarSelectInvoices.Value;
if (progressCount++ == maxCount || progressCount==invoiceCount )
{
progBarSelectInvoices.Value = 0;
progressCount = 0;
pnlProgress.Visible = false;
Application.DoEvents();
}
else
{
progBarSelectInvoices.Value++;
progressCount= progBarSelectInvoices.Value++;
}
Application.DoEvents();
Con suerte, esto le ayudará a resolverlo si analizamos lo que está sucediendo aquí. Examinemos lo que sucede cuando ingresa al bucle 6003rd. Asumiré que progBarSelectInvoices.Value == 6002
en este punto:
¿Qué hace esta línea?
progresbarValue = progBarSelectInvoices.Value++;
Al final. progresbarValue == 6004
yprogBarSelectInvoices == 6003
progresbarValue
nunca se vuelve a utilizar, por lo que probablemente se podría tirar, pero no estoy seguro
Luego saltamos hacia abajo y hacemos un montón de otras cosas y golpeamos esta línea:
progressCount = progBarSelectInvoices.Value;
Aquí progressCount == 6003
y luego hacemos esto:
if (progressCount++ == maxCount || progressCount==invoiceCount)
Entonces, ¿qué sucede aquí, si maxCount == 6004
la primera parte de esto es false
PERO ahora progessCount == 6004
? Sabemos que si maxCount
es 6004, entonces invoiceCount == 6003
(de esta línea maxCount = invoiceRecord.Count + 1;
), pero ahora progressCount == 6004
esto también es falso. Esto significa que ejecutamos la parte else.
progBarSelectInvoices.Value++;
progressCount= progBarSelectInvoices.Value++;
¿Qué hace esto? Bueno, en la primera línea lo incrementamos progBarSelectInvoices.Value
para que ahora sea 6004. Luego pasamos a la segunda línea donde lo configuramos progressCount
en 6004, pero luego incrementamos el valor de la barra de progreso nuevamente, por lo que ahora es 6005. Luego volvemos a la parte superior del ciclo y lo primero que hacemos es volver a incrementar la barra de progreso, lo que nos lleva a 6006.
Personalmente, trato de evitar hacer declaraciones previas o posteriores al incremento en declaraciones if, ya que pueden hacer que el código sea difícil de leer. En este caso, definitivamente lo desaconsejaría.
Cómo solucionarlo
Una forma de solucionar este problema: si está seguro de que solo tiene 6004 registros y, por lo tanto, solo ejecutará el ciclo while 6004 veces, haga esto (tenga en cuenta, recomiendo que mueva el incremento al final de el ciclo while para que haya terminado el trabajo antes de indicar el progreso)
while (invoiceRecord.MoveLast())
{
// All your other code here
progBarSelectInvoices.Value++;
Si desea asegurarse de no exceder el valor máximo, simplemente puede agregar una verificación rápida
while (invoiceRecord.MoveLast())
{
// All your other code here
if (progBarSelectInvoices.Value < progBarSelectInvoices.Maximum)
progBarSelectInvoices.Value++;
Luego puede eliminar el negocio if / else al final del ciclo que está verificando el maxCount y restableciendo la barra de progreso o incrementándola.
Nota al margen
Por la presencia de la línea Application.DoEvents()
y el hecho de que no obtiene una excepción al incrementar el valor de la barra de progreso, tengo la sospecha de que está ejecutando este bucle en el hilo de la interfaz de usuario. Siempre que necesite agregar Application.DoEvents()
el código de su controlador de eventos, es un buen momento para preguntarse "¿Cómo puedo sacar este trabajo del hilo de la interfaz de usuario?" Llamar Application.DoEvents()
casi nunca es una buena idea. Mira aquí y aquí
Debe mover ese código a un hilo de fondo. Lo único que debe tener en cuenta es que necesitaría usar una llamada de invocación para actualizar el valor de la barra de progreso.
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras