I made a C# application which iterates through an image folder in order to classify the images, The problem is that during the execution. After it classified some images, the program crashes without any error, it just freezes with no error message.
private void ImageProcessing(string filename)
{
panel1.Controls.Clear();
pictureBox1.Image = new Bitmap(filename);
var predictions = _logic.Classify(filename);
foreach (var item in predictions)
{
if (this.InvokeRequired)
{
this.BeginInvoke((MethodInvoker)delegate ()
{
new Label() { Text = $"{item.Label} : {item.Confidence}", Parent = panel1, Dock = DockStyle.Top };
});
}
else
{
new Label() { Text = $"{item.Label} : {item.Confidence}", Parent = panel1, Dock = DockStyle.Top };
}
}
this.CompareScores(predictions);
var biggestCompare = this.CompareScores(predictions);
switch (biggestCompare.Label)
{
case "Has no Lighter":
TurnON_NOK_Lamp();
break;
case "Has Lighter":
TurnOn_OK_Lamp();
break;
}
}
private void Start()
{
Thread.Sleep(1000);
if (filenames.Length == 0)
{
NoFileLabel.Visible = false;
this.TurnOFF_LightTower();
}
else
{
foreach (string filename in filenames)
{
ImageProcessing(filename);
Thread.Sleep(1000);
this.TurnOFF_LightTower();
pictureBox1.Image = null;
pictureBox1.Invalidate();
}
foreach (string filename in filenames)
{
File.Delete(filename);
}
}
}
CodePudding user response:
Apparently you are calling Start()
and hence ImageProcessing()
methods from UI thread. If there are any long-running calculations (and I believe there are some) then UI will become unresponsive, because you are blocking message processing loop for a long time and all UI is based on this message processing.
I recommend using switching to async methods for any long-running calculations. Check https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming for detailed information.
In your case the ImageProcessing()
and Classify()
methods could look like:
private async Task ImageProcessingAsync(string filename)
{
pictureBox1.Image = new Bitmap(filename);
var predictions = await _logic.ClassifyAsync(filename);
foreach (var item in predictions)
{
label1.Text = $"{item.Label} : {item.Confidence}";
}
//await CompareScoresAsync(predictions);
var biggestCompare = this.CompareScoresAsync(predictions);
switch (biggestCompare.Label)
{
case "Has no Lighter":
TurnON_NOK_Lamp();
break;
case "Has Lighter":
TurnOn_OK_Lamp();
break;
}
}
public Task<List<Prediction>> ClassifyAsync(string filename)
{
return Task.Run(() =>
{
// TODO: prepare the result
return result;
});
}
Also you don't need to create a new label every time, so you could put a label once in the designer and then only change its Text.
Thread.Sleep()
also is not desirable since it's blocking the executing thread and UI again becomes unresponsive. You could use await Task.Delay()
instead.