2015-10-14 4 views
0

Не знаю, что я делаю неправильно, но у меня есть цикл, который должен печатать 15 строк в многострочном текстовом поле, и он печатает 10 тысяч (32 767, если быть точным). У меня есть 2 класса: мой класс формы (DISMgui.cs) и мой логический класс (DISM.cs).Циклы повторения цикла forEach

Форма имеет текстовое поле (txtWimFile) для файла, кнопки (btnMount), рабочего стола (bwMountWim) и текстового поля ML (txtOutput) для вывода.

Сценарий: введите имя файла в txtWimFile (например, C: \ Temp \ Win7x64.wim). Нажмите btnMount. Это вызывает bwMountWim.RunWorkerAsync():

private void btnMount_Click(object sender, EventArgs e) 
{ 
    if (!String.IsNullOrEmpty(txtWimFile.Text)) 
     bwMountWim.RunWorkerAsync(); 
    else 
     MessageBox.Show("WIM file text box returned null!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 

, который вызывает метод из класса DISM (ImageInfo):

private void bwMountWim_DoWork(object sender, DoWorkEventArgs e) 
{ 
    imageInfo = DISM.ImageInfo(GetTxtWimFile(), this); 
} 

ImageInfo использует DismApi для сбора информации о WIM изображения и возвращает данные:

public static DismImageInfoCollection ImageInfo(string wimFile, DISMgui that) 
{ 
    DismImageInfoCollection info = null; 

    try 
    { 
     info = DismApi.GetImageInfo(wimFile); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 

    return info; 
} 

фон работник RunWorkerCompleted возвращает информацию в txtOutput.Text:

private void bwMountWim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    foreach (DismImageInfo info in imageInfo) 
    { 
     Output = ""; 
     Output += "Image information for image " + WimFile + System.Environment.NewLine; 
     Output += System.Environment.NewLine; 
     Output += String.Format("Image index   : {0}" + System.Environment.NewLine, info.ImageIndex.ToString()); 
     Output += String.Format("Image name   : {0}" + System.Environment.NewLine, info.ImageName.ToString()); 
     Output += String.Format("Image Internal Size : {0} MB" + System.Environment.NewLine, (info.ImageSize/1048576).ToString("N0")); 
     Output += String.Format("Image Description : {0}" + System.Environment.NewLine, info.ImageDescription.ToString()); 
     Output += String.Format("Image Type   : {0}" + System.Environment.NewLine, info.ImageType.ToString()); 
     Output += String.Format("Image Installation : {0}" + System.Environment.NewLine, info.InstallationType.ToString()); 
     Output += String.Format("Image Prod Name  : {0}" + System.Environment.NewLine, info.ProductName.ToString()); 
     Output += String.Format("Image Prod Suite : {0}" + System.Environment.NewLine, info.ProductSuite.ToString()); 
     Output += String.Format("Image Prod Type  : {0}" + System.Environment.NewLine, info.ProductType.ToString()); 
     Output += String.Format("Image Prod Version : {0}" + System.Environment.NewLine, info.ProductVersion.ToString()); 
     Output += String.Format("Image Bootable  : {0}" + System.Environment.NewLine, info.Bootable.ToString()); 
     Output += String.Format("Image Architecture : {0}" + System.Environment.NewLine, info.Architecture.ToString()); 
     Output += String.Format("Image Edition ID : {0}" + System.Environment.NewLine, info.EditionId.ToString()); 

    } 

    txtOutput.Text = Output; 
} 

DismApi настроен так, чтобы иметь возможность обрабатывать WIM с несколькими индексами, хотя WIM, с которыми я обычно работаю, имеют только один.

Как я понимаю свою логику, в «imageInfo» должен быть только один «информационный» объект и таким образом запустить цикл только один раз. Тем не менее, я получаю более 30 000 возвращенных строк (см. here, слишком много для пастабина). По иронии судьбы, последние 15 строк - это именно то, как это должно быть.

Если кто-нибудь может пролить свет на то, почему он это делает, и что я могу сделать, чтобы исправить это, я был бы признателен. У меня такое чувство, что это нечто глупое.

Код для Output собственности:

public string Output 
{ 
    get { return output; } 
    set 
    { 
     if (!String.IsNullOrEmpty(value)) 
     { 
      output += value; 
     } 
    } 
} 
+5

активизировали Вы через код в отладчике, чтобы увидеть количество элементов в 'imageInfo'? – Tim

+1

@Tim Не имеет значения, поскольку каждый цикл сбрасывает 'Output' в пустую строку, прежде чем конкатенировать другие значения. Таким образом, только значения из последней итерации будут установлены в 'textOutput.Text'. – juharr

+2

Что такое 'Output'? Как это определяется? –

ответ

2

Так почему я спросил о Output, я подумал, что это была простая строка или свойство с чем-то еще происходит внутри него. Ваш «сеттер» запутывает вас.

Вот ваше имущество от вашего комментария:

public string Output 
{ 
    get { return output; } 
    set 
    { 
     if (!String.IsNullOrEmpty(value)) 
     { 
      output += value; 
     } 
    } 
} 

Во-первых, вы конкатенации к Output, как это. Если бы это была простая строка, все хорошо.

Output += String.Format(...); 

Но вместо этого, благодаря +=, вы в основном делают это:

Output = Output + String.Format(...); 
     ^^^^^^^^^^^^^^ // all of that is the "value" your passing into the property 

Другими словами:

if (!String.IsNullOrEmpty(value)) 
{ 
    // The value of "value" is everything that was in output, 
    // plus the additional string, which gets tacked on to the end of "output" 
    output += value; 
} 

Чтобы исправить это, вы должны повторно инженер это. Например, удалите один из += либо в свой установщик свойств, либо в цикле .


Я думаю, что я бы заменить свойство с StringBuilder:

var output = new StringBuilder(); 
output.AppendLine("Image information for image " + WimFile); 
output.AppendLine(""); 
output.AppendLine(""); 
output.AppendLine(String.Format("Image index   : {0}", info.ImageIndex.ToString())); 
... 
... 
txtOutput.Text = output.ToString(); 
+0

Там есть другая логика, которая меня тоже беспокоит. Подобно тому, что у вас есть цикл foreach, который вытирает все значения из предыдущих итераций, так что в TextBox появятся только значения последней итерации. Это может быть что-то, что можно проверить, или, может быть, просто вытащите цикл, если есть только одно значение для повторения. –

+1

Я сам ругаюсь ... Я знал, что это что-то простое, но я никогда не думал проверить свойство Output. Поскольку txtOutput действует как журнал, я думал, что он всегда + =, и не думал, что двойная конкатенация будет иметь место. Изменение моего цикла на just = устранило проблему. – jparnell8839

+0

Очистка строки была всего лишь быстрой отладкой, чтобы убедиться, что она не циклически повторяется несколько раз (так как я знал, что мой WIM имеет только 1 индекс). Он удаляется, но я открыт для других предложений, которые у вас могут быть. Я все еще изучаю C# и OOP в целом и стараюсь поддерживать хорошую форму и не развивать вредные привычки. – jparnell8839

Смежные вопросы