#c# #.net #visual-studio
#c# #.net #visual-studio
Вопрос:
Я работаю над программой .NET, которая предназначена для перебора выбранного каталога и позволяет переименовывать файлы изображений после отображения изображений. По моему коду я чувствую, что около 98% программы выполнено, но я использовал while
цикл для ожидания нажатия кнопки, чтобы разрешить переименование файла изображения. Тем не менее, while
цикл замораживает программу каждый раз while
, когда цикл повторяется.
Как я могу system("pause");
, например, в C while
приостановить цикл без замораживания программы и создания бесконечного цикла или как я могу while
автоматически приостановить цикл до нажатия кнопки?
Вот лакомый кусочек кода для цикла:
paused = true;
bool X = false;
label2.Text = "please choose a file name and press next";
//while statement
while (X == false)
{
if (paused == false)
{
//Renames filename
string newFileName = filenameTextbox.Text;
//Adds filename to selected directory where user wishes to send file to
string outputFile = destinationDirectory "\" intCounter fileNameOfficial;
//Pause statement to move to next operand..
//Copies post iterated file to selected directory
File.Copy(inputFile, outputFile, true);
X = true;
}
}
Ниже приведен полный код.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
namespace recursionBitches
{
public partial class fileSorter : Form
{
bool paused = true;
public fileSorter()
{
InitializeComponent();
}
private void browseFrom_Click(object sender, EventArgs e)
{
//Warning dialouge for selecting a large file.
MessageBox.Show("Warning, before selecting the origination file, it is important to note that choosing too large of a directory (for example, my documents or 'C://') more than likely will cause this program to freeze. ");
MessageBox.Show("You have been warned");
//Choose the originating dir path. This dir path is to be later sorted using recursion.
//Once the originating dir path is chosen, it is added to the label above the button.
if (fromBrowse.ShowDialog(
) == DialogResult.OK)
{
this.originationLabel.Text = fromBrowse.SelectedPath;
}
}
private void browseTo_Click(object sender, EventArgs e)
{
//Choose the send to dir path. This dir path is to later have the files that are sorted sent to it.
//Once the to dir path is chosen, it is added to the label above the button.
if (toBrowse.ShowDialog(
) == DialogResult.OK)
{
this.sendingLabel.Text = toBrowse.SelectedPath;
}
}
private void sortButton_Click(object sender, EventArgs e)
{
string fileExtension = "*" fileExtensionTextbox.Text;
//Check from path to ensure they are set to a user defined path.
int intCounter = 1;
if (originationLabel.Text != "From")
{
//Check to path to ensure it is set to a user defined path.
if (sendingLabel.Text != "To")
{
//Recursion stuff...
string sourceDirectory = fromBrowse.SelectedPath;
string destinationDirectory = toBrowse.SelectedPath;
//Sends origination path to function ae this is a function call. its num = 8675309... I think its name is Jenny.
recursiveRecursion(sourceDirectory, destinationDirectory, fileExtension, intCounter);
}
else
{
//Message box that says it is required to
MessageBox.Show("You dun goofed");
}
}
else
{
//Yup, it's a message box.
//That was an unhelpful comment....
/Aalmost as unhelpful as this comment
// This is what happens when I program stoned.
MessageBox.Show("You dun goofed");
}
//Grabs the path of the originating directory.
//After the originating directory path is choosen, send the path to a recursion function
//which will search the folders and sort the files in the dir. path.
}
private void originationLabel_Click(object sender, EventArgs e)
{
MessageBox.Show("Silly user, I am a label. I dont even click");
}
private void sendingLabel_Click(object sender, EventArgs e)
{
MessageBox.Show("Silly user, I am a label. I dont even click");
}
//Recursion function which grabs the directory path, uses a foreach loop to iterate through the files.
//Whilst each file is iterated through, have the recursive function select the files by extension and copy
//the files to another directory chosen by the user.
private void recursiveRecursion(string sourceDirectory, string destinationDirectory, string fileExtension, int intCounter)
{
//Select files Path and stuff
string[] filenames = Directory.GetFiles(sourceDirectory, fileExtension);
//foreach (string directoryName in directoryNames)
string[] directoryNames = Directory.GetDirectories(sourceDirectory);
//dir is the file name, as in for each file name in directory do the thing in this recursion loop thingy.
foreach (string fileName in filenames)
{
try
{
if (File.Exists(fileName))
{
//Don't use recursion. It is a file
//copy files here and stuff.
intCounter ;
//For the destination file ae dir2 to work, I need to get the file name from the file path.
//Currently dir is the file path.
//Enter code here to get the file name from the file path.
//Displays on label name of the file.
this.filesortTextbox.Text = "the file being copied is " fileName;
//Gets filename from path
string fileNameOfficial = Path.GetFileName(fileName);
//Enters text of filename into filename textbox
filenameTextbox.Text = fileNameOfficial;
//For copying purposes, adds filename to originating directory path.
string inputFile = sourceDirectory "\" fileNameOfficial;
//Assigns image from the origination directory.
Image img = Image.FromFile(inputFile);
// Shows image in the image viewer...
iteratedPicturebox.Image = img;
iteratedPicturebox.Width = img.Width;
iteratedPicturebox.Height = img.Height;
//Allows the user to change file name, after changing filename allows
//user to go to next file to rename. This is awesome for files...
paused = true;
bool X = false;
label2.Text = "Please choose a file name and press next.";
//while statement
while (X == false)
{
if (paused == false)
{
//Renames filename
string newFileName = filenameTextbox.Text;
//Adds filename to selected directory where user wishes to send file to.
string outputFile = destinationDirectory "\" intCounter fileNameOfficial;
//Pause statement to move to next operand..
//Copies post iterated file to selected directory.
File.Copy(inputFile, outputFile, true);
X = true;
}
}
}
else
{
//This really has an unknown pourpose, admittably keeping here for good luck...
Console.WriteLine("{0} is not a valid file or directory.", fileName);
}
}
catch (Exception e)
{
//What process failed you ask? Good question mate.
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
//Long story short for each directory contained in the list of directories.
//Do the stuff listed in the foreach statement.
foreach (string directoryName in directoryNames)
{
try
{
if (Directory.Exists(directoryName))
{
//If this is a directory, send the thing through itself.
// MessageBox.Show("now going through the " directoryName " directory");
recursiveRecursion(directoryName, destinationDirectory, fileExtension, intCounter);
this.directoryIterated.Text = "The Current Directory The Files Are being copied from is " directoryName;
}
}
catch (Exception e)
{
Console.WriteLine("The process failed: {0}", e.ToString());
}
}
}
private void fileExtensionTextbox_TextChanged(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void directoryIterated_Click(object sender, EventArgs e)
{
MessageBox.Show("I am a label. I don't even click");
this.directoryIterated.Text = "You pressed me.";
}
private void kill_Click(object sender, EventArgs e)
{
Close();
}
private void filesortTextbox_Click(object sender, EventArgs e)
{
MessageBox.Show("I am a label. I don't even click.");
this.directoryIterated.Text = "You pressed me.";
}
private void iteratedPicturebox_Click(object sender, EventArgs e)
{
MessageBox.Show("I am a picture box, I don't even click.");
}
private void nextButton_Click(object sender, EventArgs e)
{
if (paused == false)
{
paused = true;
}
else
{
paused = false;
}
}
}
}
Комментарии:
1. Похоже, вы используете цикл while, который выполняется бесконечно, чтобы «приостановить» программу. Я не уверен, насколько хорошо это будет работать, но попробуйте добавить
Application.DoEvents();
внутри этого цикла while и расскажите мне, как это происходит2. Ну, да, ваша программа зависнет, если она выполняет этот цикл. Пока поток пользовательского интерфейса выполняет цикл, он не может очень хорошо реагировать на нажатие кнопки. В чем именно причина цикла? Кроме того, вместо вашего
recursiveRecursion
, взгляните наDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383458.aspx , иDirectory.EnumerateDirectories
, что несколько упростит вашу жизнь.3. Я бы вообще избегал цикла обработки. Или оставьте это, но заставьте его вызывать модальное диалоговое окно для каждого ввода.
4. @mazzzzz: Использование
Application.DoEvents()
никогда не бывает правильным. Оставьте поток пользовательского интерфейса для выполнения работы с пользовательским интерфейсом. Пусть вычисления и другие вещи выполняются в отдельных потоках, тогда вам не придется прибегать к использованию этого ужасного метода в первую очередь.5. Поверьте мне, я знаю, но я не собираюсь объяснять правильный способ сделать это в комментарии, и у меня нет времени, чтобы написать полное объяснение того, почему это ужасная идея, поэтому я просто сначала убедился, что это проблема. Запуск его в асинхронном режиме был бы вариантом, но лучшим способом было бы изменить порядок приложения, чтобы оно работало вне событий. Следовало бы добавить это в мой последний комментарий, хотя ^^
Ответ №1:
Рассмотрите возможность использования a BackgroundWorker
для вашего цикла обработки. Это позволяет вам обрабатывать это в фоновом потоке и не будет замораживать ваш основной поток пользовательского интерфейса (что и происходит)
Комментарии:
1. На самом деле это не ответ на вопрос, поскольку речь шла о взаимодействии с пользователем, а не о выполнении работы в фоновом режиме.
Ответ №2:
Вместо того, чтобы пытаться остановить выполнение, я бы отобразил диалоговое окно:
- Создайте форму, например:
FileRenameDialog
. - Добавьте общедоступные свойства в форму, которую вы можете использовать для задания: текст и т. Д.
- Создайте экземпляр формы. например:
FileRenameDialog reuseme
- Всякий раз, когда пользователю нужно сделать выбор, введите текст в диалоговом окне. например:
reuseme.Source = "The current file being copied...";
- Отобразить диалоговое окно для пользователя как модальное, например:
var dlgResult = reuseme.ShowDialog(this);
- Делайте то, что вам нужно, с результатом, например:
if (dlgResult == DialogResult.OK) {...do stuff with the properties of reuseme...}