Reputation: 3
So I've made a simple Mp3 to Wave converter using NAudio. Everything works fine, except that there is a bug that I really don't like. Here's the section of the code that does the conversion:
foreach (mp3file file in fileList){
string outputfilename = fbd.SelectedPath + "\\" + file.name + ".wav";
using (Mp3FileReader reader = new Mp3FileReader(file.path)){
using (WaveStream convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)){
WaveFileWriter.CreateWaveFile(outputfilename, convertedStream);
}
}
progressBar.PerformStep(); //This isn't working.
}
I wanted the program to make the progressbar perform a step each time a song gets converted, but instead the progress bar stays empty for the entire conversion process and then increases all at once when the conversion is finished. It's not that worrying tho, if there's not simple solution I'll bear this bug.
Upvotes: 0
Views: 1040
Reputation: 2710
Your Conversion and progressbar updation is taking place on same thread so updating the GUI components do not take place until the conversion is completed just use Application.doEvents()
as it will process all pending messages in que of application after progressbar.PerformStep()
then it will not fill up at once at the end of processing but keeps on updating with the processing
foreach (mp3file file in fileList){
string outputfilename = fbd.SelectedPath + "\\" + file.name + ".wav";
using (Mp3FileReader reader = new Mp3FileReader(file.path)){
using (WaveStream convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)){
WaveFileWriter.CreateWaveFile(outputfilename, convertedStream);
}
}
progressBar.PerformStep(); //This isn't working alone
Application.DoEvents(); //This is working fine now
}
Upvotes: 0
Reputation: 14064
You should be using either BackgroundWorker or async and await to perform for progress bar updates. The loops generally block the WinForms and it looks like it is freezed and nothing is happening. Whereas the BackgroundWorker
reports the UI thread if any changes has been made.
In the constructor
{
backgroundWorker.RunWorkerAsync();
}
BackgroundWorker implementation
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
var backgroundWorker = sender as BackgroundWorker;
foreach (mp3file file in fileList)
{
string outputfilename = fbd.SelectedPath + "\\" + file.name + ".wav";
using (Mp3FileReader reader = new Mp3FileReader(file.path))
{
using (WaveStream convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)){
WaveFileWriter.CreateWaveFile(outputfilename, convertedStream);
}
backgroundWorker.ReportProgress();
}
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Do something When the loop or operation is completed.
}
Upvotes: 2
Reputation: 1520
Assuming that this is all taking place on the UI thread, try calling the Refresh() method on the progress bar object, to force it to redraw.
foreach (mp3file file in fileList){
string outputfilename = fbd.SelectedPath + "\\" + file.name + ".wav";
using (Mp3FileReader reader = new Mp3FileReader(file.path)){
using (WaveStream convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)){
WaveFileWriter.CreateWaveFile(outputfilename, convertedStream);
}
progressBar.PerformStep(); // This isn't working.
progressBar.Refresh(); // This might fix it
}
But it's better to offload this sort of work to a BackgroundWorker.
Upvotes: 0