I'm currently using a loop in C# to generate files, but the program takes a few seconds to actually do this and I feel the program user would benefit from a progress bar that updates to tell them how far the loop is through so they can estimate when the loop is going to finish and all of their files are generated.
I was wondering if there was a way to calculate the time it's going to take a loop to complete or update a progress bar with the loop to show how much progress the loop has left.
Here's my loop.
String GeneratedLevelName;
int levelx = 0;
int levely = 0;
for (int i = 0; i < GmapLevelArea; i ++) {
if (levelx >= (GmapWidth - 1)) {
levelx = 0;
levely ++;
GeneratedLevelName = (GmapPrefix + "_" + levelx + "_" + levely + ".nw");
File.Copy(ApplicationDirectory + TemplateFileName, GmapDirectory + GeneratedLevelName);
GmapFile.AppendLine('"' + GeneratedLevelName + '"' + ",");
} else {
levelx ++;
GeneratedLevelName = (GmapPrefix + "_" + levelx + "_" + levely + ".nw");
File.Copy(ApplicationDirectory + TemplateFileName, GmapDirectory + GeneratedLevelName);
GmapFile.Append('"' + GeneratedLevelName + '"' + ",");
}
}
Any help is greatly appreciated.
Since it would be difficult to time the File.Copy, I think you should just base your progress bar on total files worked on.
So if you have a progress bar: pb
pb.Minimum = 0;
pb.Maximum = GMapLevelArea;
then set the value of the progress bar to you i value
pb.Value = i;
Now when I usually use progress bars like this, I usually don't update ever iteration. I usually update after a few iterations.
So to do that I usually check for the iteration count:
if(i % 10 == 0) //only true when i is a multiple of 10
pb.Value = i;
Then at the end of the loop, if it doesn't happen to be a multiple of your update, you can either set the progress bar to its maximum value or reset it to zero to let them no its done.
pb.Value = GMapLevelArea; or pb.Value = 0;
It depends on how consistent your files are generated (do they all take a second, or take some longer than others?) and if you know how many you are going to generate. In the easiest case, you can estimate the time by taking the number of files to generate. For example if you create 50 files, you can increment the progress bar by two percent after a file is generated.
Related
my goal is to calculate how much space a file occupies in memorycache ,
to do this I made a method that loads thousands of objects into memory and calculates the difference of some values between before loading the objects and after ,
this before file addition:
Process p = Process.GetCurrentProcess();
long memoriaNonPaginata = p.NonpagedSystemMemorySize64;
long memoriaPaginata = p.PagedMemorySize64;
long memoriaDiSistema = p.PagedSystemMemorySize64;
long ramIniziale = memoriaNonPaginata + memoriaPaginata + memoriaDiSistema;
I add files:
while (counter < numeroOggettiInCache)
{
string k = counter.ToString();
data = data + k.Substring(0,1);
int position = r.Next(0, 28000);
data = data.Remove(position, 1);
_cache.CreateEntry("cucu" + counter.ToString());
_cache.Set("cucu" + counter.ToString(), data, opt);
counter++;
}
I'm going to calculate the values later:
Process p1 = Process.GetCurrentProcess();
long memoriaNonPaginataPost = p1.NonpagedSystemMemorySize64;
long memoriaPaginataPost = p1.PagedMemorySize64;
long memoriaDiSistemaPost = p1.PagedSystemMemorySize64;
long ramFinale = memoriaNonPaginataPost + memoriaPaginataPost + memoriaDiSistemaPost;
I ask if the properties I used (NonpagedSystemMemorySize64,PagedMemorySize64,PagedSystemMemorySize64) are correct and sufficient to calculate how much space the cached files use, thank you,regards
I've been given a homework assignment to code the first-fit algorithm, it's meant to assign a set number of jobs to a set number of memory blocks according to the first-Fit algorithm. So far I have the algorithm working and assigning jobs correctly; however, my problem is when my queued jobs are output to the console my loop doesn't iterate through all jobs being sent to queue, it just shows the initial job being sent to queue and its size until all jobs that were meant to be sent to queue have been iterated through.
This might be very simple but I can't seem to figure it out.... Anything else needed just ask and I can provide. Thank you.
public void firstFit(int counter, int JobIndex)
{
Counter = counter;
jobIndex = JobIndex;
do {
if (jobSize[jobIndex] > memorySize[Counter-1])
{
Counter += 1;
}
else
{
Console.Text += Environment.NewLine + "Job " + (jobIndex+1) + " of size "
+ jobSize[jobIndex] +
" has been loaded into memory block:"
+ Counter;
memorySize[Counter-1] = memorySize[Counter-1]-jobSize[jobIndex];
Console.Text += Environment.NewLine + "The size of memory block " + Counter + " is now " + memorySize[Counter-1];
Counter = 1;
jobIndex += 1;
}
} while (Counter <= blocks && jobIndex < jobs);
for (int i = 0; i < jobs-jobIndex; i++ ){
jobQ = jobIndex;
if (jobQ < jobs)
{
Console.Text += Environment.NewLine + "Job " + (jobQ+1) + " of size " + jobSize[jobQ] + " is sent to waiting queue!";
}
}
Job 1 of size 45 has been loaded into memory block:1 The size of
memory block 1 is now 16
Job 2 of size 1230 has been loaded into memory block:2 The size of
memory block 2 is now 410
Job 3 of size 325 has been loaded into memory block:2 The size of
memory block 2 is now 85
Job 4 of size 303 has been loaded into memory block:3 The size of
memory block 3 is now 131
Job 5 of size 1178 has been loaded into memory block:5 The size of
memory block 5 is now 393
Job 6 of size 1276 has been loaded into memory block:6 The size of
memory block 6 is now 426
Job 7 of size 965 has been loaded into memory block:7 The size of
memory block 7 is now 322
Job 8 of size 537 is sent to waiting queue!
Job 8 of size 537 is sent to waiting queue!
Job 8 of size 537 is sent to waiting queue!
You have this code at the end:
for (int i = 0; i < jobs-jobIndex; i++ )
{
jobQ = jobIndex;
if (jobQ < jobs)
{
Console.Text += Environment.NewLine + "Job " + (jobQ+1) + " of size " +
jobSize[jobQ] + " is sent to waiting queue!";
}
}
The value of jobQ is the same each time through the loop, so of course it's going to print the same thing every time. Is it possible you meant the first line in the loop to read:
jobQ = jobIndex + i;
??
Sorted. Thank you Ryan for pointing me in the right direction. Problem was i wasn't trying to get the job number of all the values that needed to go into the Queue, i was just getting the job number of jobQ+1, which would always be the same job, the first job that didn't fit. The same for my jobSize.
Here's the bit of code i had to change:
for (int i = 0; i < jobs-jobIndex; i++ ){
jobQ = jobIndex;
if (jobQ < jobs)
{
Console.Text += Environment.NewLine + "Job " + (jobQ+(i+1)) + " of size " +
jobSize[jobQ+i]) + " is sent to waiting queue!";
}
}
This is from Joseph Albahari's excellent C# 5.0 in a Nutshell book
In one of his chapters, he mentions a race-condition in this code block ..my guess is it's meant to be pretty self-evident, as he didn't bother to specify where it was but running the code multiple times I was unable to produce the said-race condition
_button.Click += (sender, args) =>
{
_button.IsEnabled = false;
Task.Run (() => Go());
};
void Go()
{
for (int i = 1; i < 5; i++)
{
int result = GetPrimesCount (i * 1000000, 1000000);
Dispatcher.BeginInvoke (new Action (() =>
_results.Text += result + " primes between " + (i*1000000) + " and " +
((i+1)*1000000-1) + Environment.NewLine));
}
Dispatcher.BeginInvoke (new Action (() => _button.IsEnabled = true));
}
I don't agree with #Serge's answer. You don't even need multiple threads to see the problem. Try to run your code in its original form and notice the output. For me it's the following and is sometimes random (I fixed the first value):
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999
1000000 primes between 5000000 and 5999999
Notice the last 2 values. They're all the same, but they should depend on i. The problem is not that the operation is not atomic, because the GUI thread will execute the actions sequentially anyway.
The reason for this occurring is that the lambda function passed to BeginInvoke takes the value of i at the moment of execution, not at the moment of initialization, so they will all see the last value of i by the time they get executed. The solution is to explicitly pass i as a parameter to the lambda like so:
for (int i = 1; i < 5; i++)
{
int result = 1000000;
Dispatcher.BeginInvoke(new Action<int>(j =>
results.Text += result + " primes between " + (j * 1000000) + " and " +
((j + 1) * 1000000 - 1) + Environment.NewLine), i);
}
This line will not be calculated atomically:
_results.Text += result + " primes between " + (i*1000000) + " and " + ((i+1)*1000000-1) + Environment.NewLine));
So being executed from 5 concurrently running threads it may produce different funny results.
I could convert the pdf pages into images. if it is less than 50 pages its working fast...
if any pdf large than 1000 pages... it acquires lot of time to complete.
any one can review this code and make it work for large file size...
i have used PdfLibNet dll(will not work in 4.0) in .NET3.5
here is my sample code:
public void ConverIMG(string filename)
{
PDFWrapper wrapper = new PDFWrapper();
wrapper.RenderDPI = Dpi;
wrapper.LoadPDF(filename);
int count = wrapper.PageCount;
for (int i = 1; i <= wrapper.PageCount; i++)
{
string fileName = AppDomain.CurrentDomain.BaseDirectory + #"IMG\" + i.ToString() + ".png";
wrapper.ExportJpg(fileName, i, i, (double)100, 100);
while (wrapper.IsJpgBusy)
{
Thread.Sleep(50);
}
}
wrapper.Dispose();
}
PS:
we need to split pages and convert to images parallely and we need to get completed status.
If PDFWrapper performance degrades for documents bigger then 50 pages it suggests it is not very well written. To overcome this you could do conversion in 50 page batches and recreate PDFWrapper after each batch. There is an assumption that ExportJpg() gets slower with number of calls and its initial speed does not depend on the size of PDF.
This is only a workaround for apparent problems in PDFWrapper and a proper solution would be to use a fixed library. Also I would suggest Thread.Sleep(1) if you really need to wait with yielding.
public void ConverIMG(string filename)
{
PDFWrapper wrapper = new PDFWrapper();
wrapper.RenderDPI = Dpi;
wrapper.LoadPDF(filename);
int count = wrapper.PageCount;
for (int i = 1; i <= count; i++)
{
string fileName = AppDomain.CurrentDomain.BaseDirectory + #"IMG\" + i.ToString() + ".png";
wrapper.ExportJpg(fileName, i, i, (double) 100, 100);
while (wrapper.IsJpgBusy)
{
Thread.Sleep(1);
}
if (i % 50 == 0)
{
wrapper.Dispose();
wrapper = new PDFWrapper();
wrapper.RenderDPI = Dpi;
wrapper.LoadPDF(filename);
}
}
wrapper.Dispose();
}
I want to display 2 sets of data on the one list box, for example, I would wont to display the 7 times table and the 8 times table on the same listbox. Here is how I get the first set of data displaying:
int awnser = 0;
int z;
z = int.Parse(textBox1.Text);
for (int i = 0; i < 11; i++)
{
awnser = z * i;
listBox6.Items.Add(z + " * " + i + " = " + awnser.ToString());
}
But how do I get a line break or separation so I can put the 8 times table just underneath?
How about this?
EDIT Insert it AFTER your loop
listBox6.Items.Add(z + " * " + i + " = " + awnser.ToString());
}
listBox6.Items.Add("--------------------");
In WPF this is easy to do using a custom template, but in WinForms I think you must do it by rendering the list items yourself.
Look at this example where they override the OnDrawItem method: http://www.syncfusion.com/FAQ/windowsforms/faq_c87c.aspx#q627q