c# Progressbar, Overflow returns negative value - c#

I'm creating a backup application. I have 5 folders in different locations what needs to be copied to one backup folder. (solved via checkbox.checked)
The main issue is that some of the folders are more than 3-4GB in total (with all subfolders) Progressbar is not updated because "maxbyte" returns a negative value. (I assume int32 overflows after 2gb file copy)
(Sorry can't explain it more in details..I'm just a beginner C# programmer)
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using memoQClientBackuTool;
namespace memoQBackupTool
{
public partial class BGWorker : Form
{
public BGWorker()
{
InitializeComponent();
}
BackgroundWorker bw;
string source = "";
string target = "";
bool isfile = false;
int filecount = 0;
int currentFileNr = 1;
string newFilename = "";
int maxbytes = 0;
public void ShowProgress(string from, string to, bool isf)
{
InitializeComponent();
source = from;
target = to;
isfile = isf;
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
GetFileData();
}
private void GetFileData()
{
if (isfile)
{
FileInfo fi = new FileInfo(source);
maxbytes = Convert.ToInt32(fi.Length);
//
//set progress bar length
//
progressBar1.Minimum = 0;
progressBar2.Minimum = 0;
progressBar1.Maximum = maxbytes;
progressBar2.Maximum = 1;
bw.RunWorkerAsync();
}
else
{
GetDirectoryInfo(source);
//
//set progress bar length
//
progressBar1.Minimum = 0;
progressBar2.Minimum = 0;
progressBar1.Maximum = maxbytes;
progressBar2.Maximum = filecount;
bw.RunWorkerAsync();
}
}
private void GetDirectoryInfo(string source)
{
string[] files = Directory.GetFiles(source);
foreach (string file in files)
{
FileInfo fi = new FileInfo(file);
maxbytes += Convert.ToInt32(fi.Length);
filecount += 1;
}
string[] folders = Directory.GetDirectories(source);
foreach (string folder in folders)
{
GetDirectoryInfo(folder);
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (isfile)
{
FileStream fs = new FileStream(source, FileMode.Open);
long FileSize = fs.Length;
FileInfo fi = new FileInfo(source);
byte[] bBuffer = new byte[(int)FileSize];
fs.Read(bBuffer, 0, (int)FileSize);
fs.Close();
UpdateLabels(fi.FullName);
newFilename = fi.Name;
try
{
FileStream fss = new FileStream(target + "\\" + newFilename, FileMode.CreateNew);
BinaryWriter biwr = new BinaryWriter(fss);
for (int i = 0; i < bBuffer.Length; i += 15000)
{
if (i + 15000 < bBuffer.Length)
{
biwr.Write(bBuffer, i, 15000);
bw.ReportProgress(15000);
}
else
{
biwr.Write(bBuffer, i, bBuffer.Length - i);
bw.ReportProgress(bBuffer.Length - i);
}
}
biwr.Close();
fss.Close();
} catch (IOException){
MessageBox.Show("Nincs olyan...");
}
}
else
{
string[] temp = source.Split('\\');
target += "\\" + temp[temp.Count() - 1];
DirectoryInfo s = new DirectoryInfo(source);
DirectoryInfo t = new DirectoryInfo(target);
CopyDirectory(s, t);
}
if (bw.CancellationPending)
{
e.Cancel = true;
return;
}
}
public void CopyDirectory(DirectoryInfo di_source, DirectoryInfo di_target)
{
if (Directory.Exists(di_target.FullName) == false)
{
Directory.CreateDirectory(di_target.FullName);
}
foreach (FileInfo fi in di_source.GetFiles())
{
newFilename = fi.Name;
FileStream fs = new FileStream(fi.FullName, FileMode.Open);
long FileSize = fs.Length;
byte[] bBuffer = new byte[(int)FileSize];
fs.Read(bBuffer, 0, (int)FileSize);
fs.Close();
UpdateLabels(fi.FullName);
if (File.Exists(di_target.ToString() + "\\" + fi.Name))
{
Random rand = new Random();
newFilename = newFilename + "_" + rand.Next(1, 10000);
}
FileStream fss = new FileStream(di_target.ToString() + "\\" + newFilename, FileMode.CreateNew);
BinaryWriter biwr = new BinaryWriter(fss);
for (int i = 0; i < bBuffer.Length; i += 500000)
{
if (i + 500000 < bBuffer.Length)
{
biwr.Write(bBuffer, i, 500000);
bw.ReportProgress(500000);
}
else
{
biwr.Write(bBuffer, i, bBuffer.Length - i);
bw.ReportProgress(bBuffer.Length - i);
}
}
biwr.Close();
fss.Close();
}
foreach (DirectoryInfo di_SourceSubDir in di_source.GetDirectories())
{
DirectoryInfo nextSubDir = di_target.CreateSubdirectory(di_SourceSubDir.Name);
CopyDirectory(di_SourceSubDir, nextSubDir);
}
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value += e.ProgressPercentage;
int copied = progressBar1.Value / 1024;
int total = maxbytes / 1024;
lbl_kbscopied.Text = copied + "/" + total;
}
delegate void UpdateLabelsDelegate(string filename);
void UpdateLabels(string fname)
{
if (!InvokeRequired)
{
lbl_filename.Text = "Copying: " + fname;
lbl_filenr.Text = "File: " + currentFileNr + "/" + filecount;
currentFileNr++;
progressBar2.Value += 1;
}
else
{
Invoke(new UpdateLabelsDelegate(UpdateLabels), new object[] { fname });
}
}
private void button1_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
bw.CancelAsync();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
Cursor.Current = Cursors.Default;
CustomMsgBox.Show("The task has been canceled", "Error", "OK");
this.Close();
}
else if (e.Error != null)
{
MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());
}
else
{
this.Close();
}
}
}
}

Report progress not in absolute values, but in relative; percentage, for example.
Let say that 1MB file is 100% of progress bar. That means that you have to initialize it with 100: progressBar1.Maximum = 100. Then every 15000 bytes that were copied is a little bit more than 1%. Instead of bw.ReportProgress(15000) do bw.ReportProgress(1).

I will suggest to use long instead of int wherever you are getting total bytes copied/uploaded so far. If I understood your code you are using int in for loop where you call ReportProgress

Related

Concurrent file access

I am running multiple instances of an application that reads first line from a file, then it deletes the first line and saves the file under the same name. I found out that in some instances the applications will crash. I created a sample program just to better understand the issues I have.
If I run four instances of this program, sometimes multiple instances attempt to delete the same line. In the end the operation succeeds, but it is not efficient. How can I improve the code to avoid this? Perhaps each instance needs to lock the file while it uses it.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;
namespace ConcurrentFileAccess
{
public partial class MainForm : Form
{
bool gbAbort = false;
public MainForm()
{
InitializeComponent();
}
void BtnCreateFileClick(object sender, EventArgs e)
{
string sFile = #"S:\Temp\concurrentFileAccess.txt";
Stopwatch stopwatch = Stopwatch.StartNew();
if (File.Exists(sFile)) {
File.Delete(sFile);
}
if (!File.Exists(sFile)) {
List<string> list = new List<string>();
var fc = File.Create(sFile);
fc.Close();
for (int i = 1; i <= 200; i++) {
list.Add(i.ToString());
}
File.WriteAllLines(sFile, list);
listBox1.Items.Add("File " + sFile + " was created and it contains 200 lines");
} else {
string[] lines = File.ReadAllLines(sFile);
int nlines = lines.Length;
listBox1.Items.Add("File " + sFile + " already exists and it contains " + nlines + " lines");
}
stopwatch.Stop();
listBox1.Items.Add("File created in " + stopwatch.Elapsed.ToString("hh\\:mm\\:ss\\.fff"));
}
void BtnDeleteFromFileClick(object sender, EventArgs e)
{
gbAbort = false;
int nlines = 9999;
while (nlines > 0) {
nlines = DeleteOneLine();
Application.DoEvents();
if (gbAbort) {
return;
}
}
}
int DeleteOneLine()
{
string sFile = #"S:\Temp\concurrentFileAccess.txt";
listBox1.Items.Add("We are in DeleteLines()...");
listBox1.SelectedIndex = listBox1.Items.Count - 1;
Application.DoEvents();
int nLinesLeft = 9999;
string line0 = string.Empty;
Stopwatch stopwatch = Stopwatch.StartNew();
int ntry = 0;
while (ntry < 100) {
try {
string[] lines = File.ReadAllLines(sFile);
List<string> list = new List<string>(lines);
nLinesLeft = list.Count;
if (nLinesLeft > 0) {
line0 = list[0];
list.RemoveAt(0);
listBox1.Items.Add("Deleted line " + line0);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
Application.DoEvents();
listBox1.Items.Add("Writing to file after line " + line0 + " was deleted");
File.WriteAllLines(sFile, list);
nLinesLeft = list.Count;
Application.DoEvents();
} else {
nLinesLeft = 0;
break;
}
} catch (Exception) {
ntry++;
listBox1.Items.Add("ntry = " + ntry + ", could not delete line " + line0 + " from file. Attempting again...");
listBox1.SelectedIndex = listBox1.Items.Count - 1;
Application.DoEvents();
Application.DoEvents();
Thread.Sleep(50);
}
}
if(ntry >= 100) {
nLinesLeft = -1; // should never get here
}
stopwatch.Stop();
listBox1.Items.Add("ntry: " + ntry + ", lines Left: " + nLinesLeft + ", elapsed = " + stopwatch.Elapsed.ToString("hh\\:mm\\:ss\\.fff"));
listBox1.SelectedIndex = listBox1.Items.Count - 1;
Application.DoEvents();
return nLinesLeft;
}
void BtnAbortClick(object sender, EventArgs e)
{
gbAbort = true;
}
void BtnOpenAppFolderClick(object sender, EventArgs e)
{
string sFile = Application.ExecutablePath;
string sPath = Path.GetDirectoryName(sFile);
Process.Start(sPath);
}
void BtnOpenFileClick(object sender, EventArgs e)
{
string sFile = #"S:\Temp\concurrentFileAccess.txt";
if(File.Exists(sFile)) {
Process.Start(sFile);
}
else {
MessageBox.Show("File " + sFile + " not found");
}
}
}
}

Httpclient Slow Memory Increase Issue - Using Tasks Multreaded Whenall

using System;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Net;
namespace Seranking_Scraper
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btnStop.Enabled = false;
}
CancellationTokenSource cts = null;
List<string> proxyList = new List<string>();
int _proxyIndex = 0;
int retries = 0;
int linesCount = 1;
int totalLinesCount;
List<Task> tasks = null;
string regex = "XXXXXX";
private static HttpClient client = null;
private async void BtnStart_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
cts = new CancellationTokenSource();
btnStart.Enabled = false;
btnStop.Enabled = true;
btnExport.Enabled = false;
btnOpen.Enabled = false;
btnClear.Enabled = false;
totalLinesCount = listBox_domains.Items.Count;
List<string> urls = new List<string>();
for (int i = 0; i < listBox_domains.Items.Count; i++)
{
urls.Add(listBox_domains.Items[i].ToString());
}
if (textBox_Proxies.Text != null)
{
for (int i = 0; i < textBox_Proxies.Lines.Length; i++)
{
proxyList.Add(textBox_Proxies.Lines[i]);
}
}
var maxThreads = (int)numericUpDown1.Value;
var q = new ConcurrentQueue<string>(urls);
tasks = new List<Task>();
for (int n = 0; n < maxThreads; n++)
{
tasks.Add(Task.Run(async () =>
{
while (q.TryDequeue(out string url))
{
await SendHttpRequestAsync(url, cts.Token);
Thread.Sleep(1);
if (cts.IsCancellationRequested)
{
break;
}
foreach (Task eTask in tasks)
{
if (eTask.IsCompleted)
eTask.Dispose();
}
}
}, cts.Token));
}
await Task.WhenAll(tasks).ContinueWith((FinalWork) =>
{
Invoke(new Action(() =>
{
btnStart.Enabled = true;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
timer1.Enabled = false;
timer1.Stop();
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Invoke((Action)(() => progressBar1.Value = 100));
if(!cts.IsCancellationRequested)
MessageBox.Show(new Form { TopMost = true }, "Completed!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}));
}, TaskContinuationOptions.OnlyOnRanToCompletion);
//var options = new ParallelOptions()
//{
// MaxDegreeOfParallelism = (int)numericUpDown1.Value
//};
//Parallel.For(0, listBox_domains.Items.Count, async j =>
//{
// await SendHttpRequestAsync(listBox_domains.Items[j].ToString());
// Thread.Sleep(10);
//});
}
private string GetProxy()
{
if (proxyList.Count <=0) return null;
if (_proxyIndex >= proxyList.Count - 1) _proxyIndex = 0;
var proxy = proxyList[_proxyIndex];
_proxyIndex++;
return proxy;
}
private async Task ToCsV(DataGridView dGV, string filename)
{
await Task.Yield();
string stOutput = "";
// Export titles:
string sHeaders = "";
for (int j = 0; j < dGV.Columns.Count; j++)
sHeaders = sHeaders.ToString() + Convert.ToString(dGV.Columns[j].HeaderText) + "\t";
stOutput += sHeaders + "\r\n";
// Export data.
for (int i = 0; i < dGV.RowCount - 1; i++)
{
string stLine = "";
for (int j = 0; j < dGV.Rows[i].Cells.Count; j++)
stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
stOutput += stLine + "\r\n";
//progressBar1.Style = ProgressBarStyle.Blocks;
//progressBar1.Value = (i / 100) * 100;
}
Encoding utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(stOutput);
FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(output, 0, output.Length); //write the encoded file
bw.Flush();
bw.Close();
fs.Close();
}
private async Task SendHttpRequestAsync(string url, CancellationToken ct)
{
var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(GetProxy(), false),
UseProxy = true
};
//httpClientHandler.MaxConnectionsPerServer = 1;
httpClientHandler.AllowAutoRedirect = true;
httpClientHandler.MaxAutomaticRedirections = 3;
try
{
using (client = new HttpClient(httpClientHandler))
{
client.Timeout = TimeSpan.FromMilliseconds(1000 * (int)numericUpDown_timeout.Value); //adjust based on your network
client.DefaultRequestHeaders.ConnectionClose = true;
ServicePointManager.DefaultConnectionLimit = 100;
//var byteArray = Encoding.ASCII.GetBytes("username:password1234");
//client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
try
{
using (HttpResponseMessage response = await client.GetAsync("xxxx))
{
if (response.IsSuccessStatusCode)
{
using (HttpContent content = response.Content)
{
//response.Dispose();
string result = await content.ReadAsStringAsync();
Regex match = new Regex(regex, RegexOptions.Singleline);
MatchCollection collection = Regex.Matches(result, regex);
try
{
if (collection.Count > 0)
{
await AddDataToDgv(url, collection[0].ToString(), collection[1].ToString(), collection[2].ToString());
}
else if (result.Contains("No data for your search query"))
{
await AddDataToDgv(url, "nodata", "nodata", "nodata");
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
await AddDataToDgv(url, "errorCount", "errorCount", "errorCount");
}
}
}
else
{
await RetriesProxyFail(url, ct);
}
}
}catch(Exception ex)
{
await RetriesProxyFail(url, ct, ex);
client.Dispose();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public async Task RetriesProxyFail(string url, CancellationToken ct, Exception ex = null)
{
client.DefaultRequestHeaders.ConnectionClose = true;
if (!cts.IsCancellationRequested)
{
retries++;
if (retries > (int)numericUpDown_Retries.Value)
{
retries = 0;
Invoke(new Action(async () =>
{
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
await AddDataToDgv(url, "timeout", "timeout", "timeout");
}));
}
else
{
await SendHttpRequestAsync(url, ct);
}
}
}
public async Task AddDataToDgv(string url, string tcost, string tTraffic, string tValue)
{
try
{
await Task.Yield();
Invoke(new Action(() =>
{
dataGridView1.Rows.Add(url, tcost, tTraffic, tValue);
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
if (Application.RenderWithVisualStyles)
progressBar1.Style = ProgressBarStyle.Marquee;
else
{
progressBar1.Style = ProgressBarStyle.Continuous;
progressBar1.Maximum = 100;
progressBar1.Value = 0;
timer1.Enabled = true;
}
}));
}
catch (Exception ex)
{
Invoke(new Action(async () =>
{
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
await AddDataToDgv(url, "error", "error", "error");
}));
}
}
private void BtnOpen_Click(object sender, EventArgs e)
{
linesCount = 1;
try
{
openFileDialog1.ShowDialog();
openFileDialog1.Title = "Please select text file that contains root domains.";
openFileDialog1.DefaultExt = "txt";
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.CheckFileExists = true;
openFileDialog1.CheckPathExists = true;
this.openFileDialog1.Multiselect = true;
myWorker_ReadTxtFile = new BackgroundWorker();
myWorker_ReadTxtFile.DoWork += new DoWorkEventHandler(MyWorker_ReadTxtFile_DoWork);
myWorker_ReadTxtFile.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MyWorker_ReadTxtFile_RunWorkerCompleted);
myWorker_ReadTxtFile.ProgressChanged += new ProgressChangedEventHandler(MyWorker_ReadTxtFile_ProgressChanged);
myWorker_ReadTxtFile.WorkerReportsProgress = true;
myWorker_ReadTxtFile.WorkerSupportsCancellation = true;
listBox_domains.Items.Clear();
foreach (String fileName_Domains in openFileDialog1.FileNames)
{
myWorker_ReadTxtFile.RunWorkerAsync(fileName_Domains);
}
}
catch (Exception ex)
{
}
}
private void OpenFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void MyWorker_ReadTxtFile_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listBox_domains.Items.Add(e.UserState.ToString());
lbl_totallines.Text = "TLines: " + linesCount++.ToString();
}
private void MyWorker_ReadTxtFile_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
public void ReadLinesToListBox(string fileName_Domains)
{
using (StreamReader sr = File.OpenText(fileName_Domains))
{
string s = String.Empty;
while ((s = sr.ReadLine()) != null)
{
myWorker_ReadTxtFile.ReportProgress(0, s);
Thread.Sleep(1);
}
}
}
private void MyWorker_ReadTxtFile_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker sendingWorker = (BackgroundWorker)sender;//Capture the BackgroundWorker that fired the event
object fileName_Domains = (object)e.Argument;//Collect the array of objects the we received from the main thread
string s = fileName_Domains.ToString();//Get the string value
ReadLinesToListBox(s);
}
private void Label2_Click(object sender, EventArgs e)
{
}
private void BtnStop_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
cts.Dispose();
btnStart.Enabled = true;
btnStop.Enabled = false;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = 100;
MessageBox.Show(new Form { TopMost = true }, "Cancelled!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private async void BtnExport_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "Site Metrics";
if (sfd.ShowDialog() == DialogResult.OK)
{
await ToCsV(dataGridView1, sfd.FileName); // Here dataGridview1 is your grid view name
}
MessageBox.Show(new Form { TopMost = true }, "Exported!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
private void BtnClear_Click(object sender, EventArgs e)
{
listBox_domains.Items.Clear();
dataGridView1.Rows.Clear();
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
}
private void BtnPasteProxies_Click(object sender, EventArgs e)
{
textBox_Proxies.Text = Clipboard.GetText();
}
private void Timer1_Tick(object sender, EventArgs e)
{
progressBar1.Value += 5;
if (progressBar1.Value > 100)
progressBar1.Value = 0;
}
}
}
The above code is working fine but the problem is it slowly increasing the memory usage. When I start it use some around 40 mb slowly its increasing I tried memory tests, the increase in memory is slow but its increasing slowly.
Any one help me whats wrong in my code?
I am testing with some 4k urls, when it reaches 2k urls my memory usage is 60 MB. Still increasing slowly.
A slow memory increase is totally normal. .NET uses Garbage Collection Memory Management approach. Now while the collection runs, every other thread has to stop. This can cause human noticeable stalls. And is one big reason GC and realtime programming do not mix that well.
To avoid those stalls, the GC is lazy with running. It is aiming for only running once - at application closure. Delays will not be that noticeable then. And it might even be able to save work, as the memory will be handed back to the OS afterwards and not be reused. Short of running finalizers, there might not be much work to be done.
There are only a few things that can force it to run earlier:
there is a danger of a OutOfMemory exception. The GC will have collected and defragmented everything it possibly could before you ever get that Exception.
you call GC.Collect(); It allows you to force a collection now. Note that this only adviseable for debugging and testing. Production code should not have this
you pick a GC strategy that differs from Desktop applciation default. There are ones that do the reachabiltiy checks in anotehr thread, to have that work not pause all threads. Ones that run regulary but avoid defragmentation. Even ones that run regulary with a upper bound on runtime (to limit the stalls).

How can i use a textBox.Text in backgroundworker without using cross thread?

This is the line in the dowork event
List<string> Result = SearchInFile(CurrentFileWithPath, textBox2.Text);
And this is the whole dowork event code
object[] CurrentStatus;
private void _FileProcessingWorker_DoWork(object sender, DoWorkEventArgs e)
{
int countmore = 0;
try
{
//object[] CurrentStatus = new object[5];
DirectoryInfo[] MySubDirectories = (DirectoryInfo[])e.Argument;
for (int i = 0; i < MySubDirectories.GetLength(0); i++)
{
DirectoryInfo MySubDirectory = MySubDirectories[i];
List<FileInfo> l = new List<FileInfo>();
CountFiles(MySubDirectory, l);
CurrentStatus = new object[6];
int totalFiles = l.Count;
CurrentStatus[3] = i.ToString();
countmore += totalFiles;
CurrentStatus[4] = countmore;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
string CurrentDirectory = "Current Directory: " + MySubDirectory.Name;
foreach (FileInfo MyFile in l)
{
CurrentStatus = new object[6];
if (_FileProcessingWorker.CancellationPending)
{
e.Cancel = true;
return;
}
if (MyFile.Extension.ToLower() == ".cs" || MyFile.Extension.ToLower() == ".vb")
{
string CurrentFile = "Current File: " + MyFile.Name;
string CurrentFileWithPath = MyFile.FullName;
CurrentStatus[0] = CurrentDirectory;
CurrentStatus[1] = CurrentFile;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
List<string> Result = SearchInFile(CurrentFileWithPath, textBox2.Text);
if (Result != null && Result.Count > 0)
{
CurrentStatus[2] = Result;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
}
}
}
}
}
catch (Exception err)
{
return;
}
}
I'm not getting errors but using a break point I see on the textBox2 text:
Text = The function evaluation requires all threads to run.
If there is no other way how to use cross thread with it ?

How can i sum a changing values in int variable ? And what is the real number of directories on hard disk?

Backgroundworker dowork event
string CurrentFileWithPath;
private void _FileProcessingWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
DirectoryInfo[] MySubDirectories = (DirectoryInfo[])e.Argument;
for (int i = 0; i < MySubDirectories.GetLength(0); i++)
{
DirectoryInfo MySubDirectory = MySubDirectories[i];
List<FileInfo> l = new List<FileInfo>();
CountFiles(MySubDirectory, l);
int totalFiles = l.Count;
object[] CurrentStatus = new object[5];
CurrentStatus[3] = i.ToString();
CurrentStatus[4] = totalFiles.ToString();
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
string CurrentDirectory = "Current Directory: " + MySubDirectory.Name;
foreach (FileInfo MyFile in l)
{
CurrentStatus = new object[5];
if (_FileProcessingWorker.CancellationPending)
{
e.Cancel = true;
return;
}
if (MyFile.Extension.ToLower() == ".cs" || MyFile.Extension.ToLower() == ".vb")
{
string CurrentFile = "Current File: " + MyFile.Name;
string CurrentFileWithPath = MyFile.FullName;
CurrentStatus[0] = CurrentDirectory;
CurrentStatus[1] = CurrentFile;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
List<string> Result = SearchInFile(CurrentFileWithPath, "static class FileShellExtension");
if (Result != null && Result.Count > 0)
{
CurrentStatus[2] = Result;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
}
}
}
}
}
catch (Exception err)
{
return;
}
Progresschanged event
private void _FileProcessingWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (typeof(object[]) == e.UserState.GetType())
{
object[] StatusMsg = (object[])e.UserState;
if (5 == StatusMsg.GetLength(0))
{
label2.Text = StatusMsg[4].ToString();
label4.Text = StatusMsg[3].ToString();
if (StatusMsg[0] != null && StatusMsg[1] != null)
{
lblCurrentDirectory.Text = StatusMsg[0].ToString();
lblStatus.Text = StatusMsg[1].ToString();
}
if (StatusMsg[2] != null)
{
if (StatusMsg[2].GetType() == typeof(List<string>))
{
List<string> l = (List<string>)StatusMsg[2];
for (int i = 0; i < l.Count; i++)
{
ListViewCostumControl.lvnf.Items.Add("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
w.WriteLine("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
}
}
}
}
}
}
CountFiles method
private void CountFiles(DirectoryInfo di, List<FileInfo> l)
{
try
{
l.AddRange(di.EnumerateFiles());
}
catch
{
string fff = "";
}
try
{
IEnumerable<DirectoryInfo> subDirs = di.EnumerateDirectories();
if (subDirs.Count() > 0)
{
foreach (DirectoryInfo dir in subDirs)
CountFiles(dir, l);
}
}
catch
{
string yyy = "";
}
}
SearchInFile method
private List<string> SearchInFile(string fileToSearch, string textToSearch)
{
List<string> l = new List<string>();
try
{
foreach (var line in File.ReadAllLines(fileToSearch))
{
if (line.Contains(textToSearch))
l.Add(line);
}
}
catch(Exception err)
{
string fff = err.ToString();
}
return l;
}
The first problem is when getting the number of directories:
private void btnProcess_Click(object sender, EventArgs e)
{
btnProcess.Enabled = false;
btnDirectory.Enabled = false;
btnCancel.Visible = true;
btnCancel.Enabled = true;
btnCancel.Text = "Cancel";
MyProgressBar.Visible = true;
_FileProcessingWorker = new BackgroundWorker();
_FileProcessingWorker.WorkerReportsProgress = true;
_FileProcessingWorker.WorkerSupportsCancellation = true;
_FileProcessingWorker.DoWork += new DoWorkEventHandler(_FileProcessingWorker_DoWork);
_FileProcessingWorker.ProgressChanged += new ProgressChangedEventHandler(_FileProcessingWorker_ProgressChanged);
_FileProcessingWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_FileProcessingWorker_RunWorkerCompleted);
string BasePath = lblDirectoryName.Text;
DirectoryInfo MyDirectory = new DirectoryInfo(BasePath);
DirectoryInfo[] MySubDirectories = MyDirectory.GetDirectories();
int SubDirectoryCount = MySubDirectories.GetLength(0);
MyProgressBar.Minimum = 0;
MyProgressBar.Step = 1;
MyProgressBar.Maximum = SubDirectoryCount;
MyProgressBar.Value = MyProgressBar.Minimum;
_LastCounter = 0;
_FileProcessingWorker.RunWorkerAsync(MySubDirectories);
}
In the click button i'm getting the sub directories.
But there are two problems.
In the dowork event when i put a break point on this line:
for (int i = 0; i < MySubDirectories.GetLength(0); i++)
I see that it contain 409 directories. But when i report the number of directories to the label4 in the dowork event
CurrentStatus[3] = i.ToString();
In the progresschanged event
label4.Text = StatusMsg[3].ToString();
I see in the end on label4 408 directories. And in D:(in this case i'm working on my D:\ directory) when i select all the directories in windows explorer make right click and properties i see only 405 directories. So what is the real number of directories ? What and how number of directories should i display in label4 ?
The second problem is when i report the number of files in dowork event:
CurrentStatus[4] = totalFiles.ToString();
And in progresschanged event show it on label2:
label2.Text = StatusMsg[4].ToString();
The problem is that the totalFiles value is changing all the time once it's 2 then it's 768 then it's 66 then 8987 but what i want to do is somehow to sum in real time the values in totalFiles so in label2 i will see first time for example: 2 then 770 then (770+66) so i will see in label2 816....to see always the sum of all the values so far.
The last problem is in the progresschanged event this loop:
for (int i = 0; i < l.Count; i++)
{ ListViewCostumControl.lvnf.Items.Add("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
w.WriteLine("Directory: " + lblCurrentDirectory.Text + "In File: " + lblStatus.Text + l[i]);
}
It might be logic somehow to take out and make this loop at this time in the program in another backgroundworker like backgroundworker2 dowork event ? If so how to do it ? The problem is when the loop have many items to add to the listView it make the program to hang until the loop finish.
Each time you execute
CurrentStatus[4] = totalFiles.ToString();
You are resetting the status value to the count of files in the current processing directory. This is why the number keeps bouncing around. Instead I would suggest:
int thisDirFiles;
thisDirFiles = l.Count;
totalFiles += thisDirFiles;
CurrentStatus[4] = totalFiles.ToString();
Now when you report progress, CurrentStatus[4] will have the running total.
For your second question, it looks to me you are trying to do too much when you are reporting progress. Manipulating ListViews can be costly, and you are probably spending more time updating the ListView than you are processing the directories, so your machine seems to freeze.

A generic error occurred in GDI+ ExternalException Was caught cant figure out why

The error is on the line:
for (int x = 0; x < myList.Count(); x++)
The x++is painted with green.
Im using backgroundoworker and I used this code same code in another form before without a backgroundworker and it worked good. Now in the other form im using a click button event to show() this form and I want to use a progressBar1 to show the progress of the backgroundowrker work.
I used now try and catch inside this for loop and it went to the catch point and showed me the error. The full exception message is:
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at mws.Animation_Radar_Preview.backGroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in D:\C-Sharp\Download File\Downloading-File-Project-Version-012\Downloading File\Animation_Radar_Preview.cs:line 163
gifImages isnt null.
This is the full code of this form:
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 DannyGeneral;
using unfreez_wrapper;
namespace mws
{
public partial class Animation_Radar_Preview : Form
{
int mtpStart;
int mtpEnd;
Picturebox1_Fullscreen pb1;
string radar_images_download_directory;
string tempRadarPngToGifDirectory;
int numberOfFiles;
UnFreezWrapper unfreez;
string path_exe;
List<string> myList;
string previewDirectory;
int animatedGifSpeed;
bool loop;
string nameOfStartFile;
string nameOfEndFile;
string previewFileName;
BackgroundWorker backGroundWorker1;
Image img;
private MemoryStream _memSt = null;
public Animation_Radar_Preview()
{
InitializeComponent();
mtpStart = Picturebox1_Fullscreen.mtp1Start;
mtpEnd = Picturebox1_Fullscreen.mtp1End;
animatedGifSpeed = Picturebox1_Fullscreen.animatedSpeed;
loop = Picturebox1_Fullscreen.looping;
pb1 = new Picturebox1_Fullscreen();
radar_images_download_directory = Options_DB.Get_Radar_Images_Download_Directory();
path_exe = Path.GetDirectoryName(Application.LocalUserAppDataPath);
tempRadarPngToGifDirectory = path_exe + "\\" + "tempRadarPngToGifDirectory";
if (Directory.Exists(tempRadarPngToGifDirectory))
{
}
else
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
previewDirectory = path_exe + "\\" + "previewDirectory";
if (Directory.Exists(previewDirectory))
{
}
else
{
Directory.CreateDirectory(previewDirectory);
}
previewFileName = previewDirectory + "\\" + "preview.gif";
loop = false;
animatedGifSpeed = 0;
unfreez = new UnFreezWrapper();
backGroundWorker1 = new BackgroundWorker();
backGroundWorker1.WorkerSupportsCancellation = true;
this.backGroundWorker1.WorkerReportsProgress = true;
backGroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backGroundWorker1_ProgressChanged);
backGroundWorker1.DoWork += new DoWorkEventHandler(backGroundWorker1_DoWork);
backGroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backGroundWorker1_RunWorkerCompleted);
backGroundWorker1.RunWorkerAsync();
progressBar1.Value = 0;
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult result1;
result1 = new DialogResult();
SaveFileDialog sd = new SaveFileDialog();
sd.Title = "Select a folder to save the animated gif to";
sd.InitialDirectory = "c:\\";
sd.FileName = null;
sd.Filter = "Gif File|*.gif;*.jpg|Gif|*.gif";
sd.FilterIndex = 1;
sd.RestoreDirectory = true;
result1 = sd.ShowDialog();
string file1 = sd.FileName;
if (result1 == DialogResult.OK)
{
File.Move(previewFileName, file1);
}
}
public void pictureBoxImage(string pbImage)
{
Image img2 = null;
try
{
using (img = Image.FromFile(pbImage))
{
//get the old image thats loaded from the _memSt memorystream
//and dispose it
Image i = this.pictureBox1.Image;
this.pictureBox1.Image = null;
if (i != null)
i.Dispose();
//grab the old stream
MemoryStream m = _memSt;
//save the new image to this stream
_memSt = new MemoryStream();
img.Save(_memSt, System.Drawing.Imaging.ImageFormat.Gif);
if (m != null)
m.Dispose();
//create our image to display
img2 = Image.FromStream(_memSt);
}
if (img2 != null)
pictureBox1.Image = img2;
label2.Text = numberOfFiles.ToString();
label6.Text = nameOfStartFile.ToString();
label4.Text = nameOfEndFile.ToString();
//File.Delete(pbImage);
}
catch(Exception err)
{
Logger.Write("Animation Error >>> " + err);
}
}
private void backGroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backGroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
List<string> myGifList;
Image gifImages = null;
//button1.Enabled = false;
Animation_Radar_Preview ap = new Animation_Radar_Preview();
//ap.FormClosing += new FormClosingEventHandler(ap_FormClosing);
FileInfo[] fi;
DirectoryInfo dir1 = new DirectoryInfo(radar_images_download_directory);
fi = dir1.GetFiles("*.png");
myList = new List<string>();
myGifList = new List<string>();
for (int i = mtpStart; i < mtpEnd; i++)
{
myList.Add(fi[i].FullName);
}
for (int x = 0; x < myList.Count(); x++)
{
try
{
gifImages = Image.FromFile(myList[x]);
gifImages.Save(tempRadarPngToGifDirectory + "\\" + x.ToString("D6") + ".Gif", System.Drawing.Imaging.ImageFormat.Gif);
}
catch (Exception ex)
{
MessageBox.Show(x.ToString() + "\r\n" + (gifImages == null).ToString() + "\r\n" + ex.Message);
}
}
myGifList = new List<string>();
dir1 = new DirectoryInfo(tempRadarPngToGifDirectory);
fi = dir1.GetFiles("*.gif");
nameOfStartFile = fi[0].Name;
for (int i = 0; i < fi.Length; i++)
{
myGifList.Add(fi[i].FullName);
//backGroundWorker1.ReportProgress(i);
nameOfEndFile = fi[i].Name.Length.ToString();
}
numberOfFiles = myGifList.Count();
unfreez.MakeGIF(myGifList, previewFileName, animatedGifSpeed, loop);
/*this.Invoke((MethodInvoker)delegate
{
pictureBoxImage(previewFileName);
});*/
}
private void backGroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pictureBoxImage(previewFileName);
}
}
}
I'm not entirely sure what is going wrong, especially as you say this same code worked previously — but it is not clear whether it worked with the same set of images.
Anyhow, the documentation for the Save method says that an ExternalException will be thrown in one of two situations:
Image was saved with the wrong format.
Image is saved to the file it was created from.
It cannot be that you are saving over the file because you are changing its extension, so it must be the wrong format. What this actually means is not clear. Perhaps one of the source images is using capabilities of the PNG format that cannot be converted to GIF, e.g. alpha channel transparency.
If I may take a moment to make some other suggestions too:
if (Directory.Exists(tempRadarPngToGifDirectory))
{
}
else
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
The empty 'success' case is not required if you invert the logic:
if (!Directory.Exists(tempRadarPngToGifDirectory)
{
Directory.CreateDirectory(tempRadarPngToGifDirectory);
}
Code that manipulates file paths such as the following:
tempRadarPngToGifDirectory = path_exe + "\\" + "tempRadarPngToGifDirectory";
You should consider using the Path class as this will handle the edge cases better and make more portable code:
tempRadarPngToGifDirectory = Path.Combine(path_exe, "tempRadarPngToGifDirectory");

Categories

Resources