directory Search using a background worker - c#

In my application, I have option to search a directory. If the user searching local drive then I'm searching the catalog first (searching the Index), then the directories
DirectoryInfo.GetDirectories("*" + AsearchString + "*",System.IO.SearchOption.AllDirectories).
In case of network searching (network folders), I am doing only directory search. Now the problem is, the user may or may not have access permission for files or folders. I am getting unauthorized exception and background worker stops right there, my confusion is how I can catch the exception (in case of PathTooLong or unauthorized exception, this happens when I am searching network drives ) so if there is an exception just log or omit it and continue working.
I am putting my work around below, I don't know why try/catch not working, or where I should move it so in case of exception it will disregard and keep going. I had to put the lots of code below, apologies for that, I appreciate any suggestions.
UPDATE:
Ignoring the exception in do work will stop the bcw, so I figured out my exception handling was incorrect. I have updated my code.
private void bwSearch_DoWork(object sender, DoWorkEventArgs e)
{
if (e.Argument != null && e.Argument.GetType() == typeof(List<string>))
{
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() => this.Cursor = Cursors.WaitCursor));
}
else
{
this.Cursor = Cursors.WaitCursor;
}
listViewBWSearchStatus = true;
List<string> par = e.Argument as List<string>;
string path = par[0];
string searchString = par[1];
try
{
if (FileSystemHelper.PathIsNetworkPath(path))
{
DirectoryInfo dInfo = new DirectoryInfo(path);
foreach (FileInfo fi in dInfo.GetFiles("*" + searchString + "*.*", System.IO.SearchOption.AllDirectories))
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() => this.Cursor = Cursors.Default));
}
else
{
this.Cursor = Cursors.Default;
}
break;
}
bwSearch.ReportProgress(0, fi);
}
foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories))
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
break;
}
bwSearch.ReportProgress(0, d);
}
}
else
{
var connection = new OleDbConnection(#"Provider=Search.CollatorDSO;Extended Properties=""Application=Windows""");
string searchDirectoryFormated = path.Replace(#"\", #"/");
// Folder name search (case insensitive), does not search sub directories
var directorySearchQuery = #"SELECT System.ItemName,System.ItemPathDisplay FROM SystemIndex " +
#"WHERE directory = 'file:" + searchDirectoryFormated + "' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%" + searchString + "%' ";
// File name search (case insensitive), does not search sub directories
var fileSearchQuery = #"SELECT System.ItemName,System.ItemPathDisplay FROM SystemIndex " +
#"WHERE directory = 'file:" + searchDirectoryFormated + "' AND System.ItemName LIKE '%" + searchString + "%' ";
connection.Open();
var command = new OleDbCommand(directorySearchQuery, connection);
Dictionary<string, string> directoryResult = new Dictionary<string, string>();
using (var r = command.ExecuteReader())
{
while (r.Read())
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
break;
}
if (!directoryResult.ContainsKey(r.GetString(1)))
{
directoryResult.Add(r.GetString(1), r.GetString(0));
DirectoryInfo dirInfoIndexed = new DirectoryInfo(r.GetString(1));
bwSearch.ReportProgress(0, dirInfoIndexed);
}
}
}
command = new OleDbCommand(fileSearchQuery, connection);
Dictionary<string, string> fileResult = new Dictionary<string, string>();
using (var r = command.ExecuteReader())
{
while (r.Read())
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
break;
}
if (!fileResult.ContainsKey(r.GetString(1)))
{
fileResult.Add(r.GetString(1), r.GetString(0));
FileInfo fileInfoIndexed = new FileInfo(r.GetString(1));
bwSearch.ReportProgress(0, fileInfoIndexed);
}
}
}
connection.Close();
DirectoryInfo dInfo = new DirectoryInfo(path);
foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories))
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
break;
}
bwSearch.ReportProgress(0, d);
}
foreach (FileInfo fi in dInfo.GetFiles("*" + searchString + "*.*", System.IO.SearchOption.AllDirectories))
{
if (bwSearch.CancellationPending)
{
e.Cancel = true;
break;
}
bwSearch.ReportProgress(0, fi);
}
}
}
//catch (UnauthorizedAccessException) { } // ignoring the exception will stop the background worker
catch (UnauthorizedAccessException) { throw;}
catch (System.Exception )
{
throw;// new Exception(ex.Message);
}
}
}
private void bwSearch_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState != null && e.UserState.GetType() == typeof(FileInfo))
{
FileInfo fInfo = e.UserState as FileInfo;
ListViewItem[] searchInfo = this.listView.Items.Find(Path.GetFileNameWithoutExtension(fInfo.Name), false);
if (searchInfo == null || searchInfo.Count() == 0)
{
string fileFullName = fInfo.FullName;
string lastAccessTime = fInfo.LastAccessTime.ToShortDateString();
string imageKey = "";
if (this.listView.SmallImageList.Images.ContainsKey(fInfo.Extension.ToLower()))
imageKey = fInfo.Extension.ToLower();
else
imageKey = Explorer._Unknown;
string strFileType = Explorer._Unknown;
fileExtensionToFileType.TryGetValue(fInfo.Extension.ToString(), out strFileType);
if (String.IsNullOrWhiteSpace(strFileType))
strFileType = Explorer._Unknown;
ListViewItem itemL = new ListViewItem(Path.GetFileNameWithoutExtension(fInfo.Name), imageKey);
itemL.Name = fInfo.Name;
itemL.Tag = fInfo;
ListViewItem.ListViewSubItem[] subItem = new ListViewItem.ListViewSubItem[]
{
new ListViewItem.ListViewSubItem(itemL, lastAccessTime),
new ListViewItem.ListViewSubItem(itemL, strFileType),
new ListViewItem.ListViewSubItem(itemL, Explorer.SizeSuffix(fInfo.Length)),
new ListViewItem.ListViewSubItem(itemL, fileFullName)
};
itemL.SubItems.AddRange(subItem);
this.BeginInvoke(new MethodInvoker(delegate
{
this.listView.BeginUpdate();
this.listView.Items.Add(itemL);
this.listView.EndUpdate();
}));
}
}
else if (e.UserState != null && e.UserState.GetType() == typeof(DirectoryInfo))
{
DirectoryInfo dInfo = e.UserState as DirectoryInfo;
string fullName = dInfo.FullName;
ListViewItem[] searchDirectories = this.listView.Items.Find(dInfo.Name, false);
if (searchDirectories == null || searchDirectories.Count() == 0)
{
ListViewItem itemL = new ListViewItem(dInfo.Name, Strings.FolderOpen);
itemL.Name = dInfo.Name;
itemL.Tag = dInfo;
ListViewItem.ListViewSubItem[] subItem = new ListViewItem.ListViewSubItem[]
{
new ListViewItem.ListViewSubItem(itemL, dInfo.LastAccessTime.ToShortDateString()),
new ListViewItem.ListViewSubItem(itemL, "File folder"),
new ListViewItem.ListViewSubItem(itemL, ""),
new ListViewItem.ListViewSubItem(itemL, fullName)
};
itemL.SubItems.AddRange(subItem);
this.BeginInvoke(new MethodInvoker(delegate
{
this.listView.BeginUpdate();
this.listView.Items.Add(itemL);
this.listView.EndUpdate();
}));
}
}
}
private void bwSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
if (e.Error.GetType() == typeof(UnauthorizedAccessException))
{
}
if (e.Error.GetType() == typeof(Exception))
{ }
}
if (e.Error == null && e.Cancelled == false)
{
_ResetEventSearch.Set();
listViewBWSearchStatus = false;
if (this.InvokeRequired)
{
this.BeginInvoke(new Action(() => this.Cursor = Cursors.Default));
}
else
{
this.Cursor = Cursors.Default;
}
}
}
UPDATE :
This part of the code searches for files or folders based on the user defined string. I didn't want to stall users thread since searching will be a pile load of work, so I introduced background worker instead. I got exception when I was trying to read directories in foreach (DirectoryInfo d in dInfo.GetDirectories("*" + searchString + "*", System.IO.SearchOption.AllDirectories)). I think, when It was trying to get directory info or file info, it got stuck since user didn't had access permission.
Initially I wasn't throwing exception, hence, after getting the exception the bcw didn't move further. Instead it reported error and raised run worker completed event. After I have added throw bcw continued working for the rest of the directories.

Related

Skipping a file which is using by another process

I am creating a C# application. This app is deleting temporary folders. But some processes are being used. That's why it can't remove them. And i have to skip those files. I hope you can help.
Code:
// Clearing folder's content (\)
void ClearFolder(string FolderName)
{
try
{
if (Directory.Exists(FolderName))
{
DirectoryInfo dir = new DirectoryInfo(FolderName);
foreach (FileInfo fi in dir.GetFiles())
{
fi.IsReadOnly = false;
fi.Delete();
CleanLog.Items.Add(fi.FullName + " " + "is found and deleted");
}
foreach (DirectoryInfo di in dir.GetDirectories())
{
ClearFolder(di.FullName);
di.Delete();
CleanLog.Items.Add(di.FullName + " " + "is found and deleted");
}
}
else
{
CleanLog.Items.Add(FolderName + " " + "is not found.");
}
}
catch (Exception Error)
{
MessageBox.Show(Error.Message, "Error", MessageBoxButtons.OK);
}
}
// Clearing folder's content (\)
private void Clean_MouseDown(object sender, MouseEventArgs e)
{
// Folder Locations
string Temp = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + #"\Temp"; // Temp
string Temp2 = Path.GetTempPath(); // %Temp%
// Folder Locations
// Clearing folders
ClearFolder(Temp);
ClearFolder(Temp2);
// Clearing folders
}
To achieve this, you can also use try catch for the delete statement like
try
{
fi.Delete();
}
catch
{
//Your message...
}

Form without movement when filling in DataGridView

I use a DataGridView as a console for an application, I need to fill it out every second, I use the following code for this:
public class dgView
{
public static DataGridView DataConsole;
public static void addLinha(int tipo_acao, string acao, string extra, int tipo_extra)
{
// INSERE LINHA NO CONSOLE
try
{
if (DataConsole == null) return;
var idLinha = DataConsole.Rows.Add();
using (var linha = DataConsole.Rows[idLinha])
{
//await Task.Delay(300);
if (tipo_acao == 0)
{
linha.DefaultCellStyle.ForeColor = Color.Teal;
linha.Cells[3].Style.ForeColor = Color.Gray;
}
else if (tipo_acao == 1)
{
linha.DefaultCellStyle.ForeColor = Color.Yellow;
linha.Cells[3].Style.ForeColor = Color.Orange;
}
else
{
linha.DefaultCellStyle.ForeColor = Color.Red;
linha.Cells[3].Style.ForeColor = Color.Magenta;
}
linha.Cells["dg_data"].Value = DateTime.Now;
linha.Cells["dg_mapa"].Value = "" + Config.Mapa + "";
linha.Cells["dg_acao"].Value = "" + Config.rm.GetString("" + acao + "") + "";
if (tipo_extra == 0)
{
linha.Cells["dg_extra"].Value = "" + extra + "";
}
else
{
linha.Cells["dg_extra"].Value = "" + Config.rm.GetString(extra) + "";
}
DataConsole.CurrentCell = DataConsole.Rows[idLinha].Cells[0];
//DataConsole.Refresh();
}
}
catch (Exception ex)
{
throw;
}
}
}
However, the form freezes and I can't move it to any part of the screen, would there be any way to solve this? Remembering that the DataGridView is not, and cannot be populated through the DataSource property, but by a constant verification in the system.
Example:
public static void Abrir(string metodoChamador)
{
try
{
Abrir:
dgView.addLinha(2, "config_Abrir", "config_Validando", 1);
Thread.Sleep(5000);
Atalho:
string AtalhoExiste = "" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk";
if (!File.Exists(AtalhoExiste))
{
dgView.addLinha(2, "config_FaltaIcone", "", 0);
Thread.Sleep(5000);
goto Atalho;
}
else
{
ProcessStartInfo info = new ProcessStartInfo(#"" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk");
Process whatever = Process.Start(info);
whatever.Dispose();
Thread.Sleep(5000);
IntPtr WinHandle = Win32.FindWindow(null, Config.Atalho);
if (WinHandle == (IntPtr)0)
{
goto Abrir;
}
}
}
catch (Exception ex)
{
throw;
}
}
It's hard to tell if you have other potential problems in the code. Basically anywhere you have Thread.Sleep(), your GUI is going to freeze.
Here's a possible refactoring of your Abrir() method, using async\await and Task.Delay() as suggested by JQSOFT:
public async static void Abrir(string metodoChamador)
{
try
{
IntPtr WinHandle = IntPtr.Zero;
do
{
dgView.addLinha(2, "config_Abrir", "config_Validando", 1);
await Task.Delay(5000);
string AtalhoExiste = "" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk";
while (!File.Exists(AtalhoExiste))
{
dgView.addLinha(2, "config_FaltaIcone", "", 0);
await Task.Delay(5000);
}
ProcessStartInfo info = new ProcessStartInfo(#"" + Directory.GetCurrentDirectory() + "\\" + Config.Atalho + ".lnk");
Process whatever = Process.Start(info);
whatever.Dispose();
await Task.Delay(5000);
WinHandle = Win32.FindWindow(null, Config.Atalho);
}
while (WinHandle.Equals(IntPtr.Zero));
}
catch (Exception ex)
{
throw;
}
}
If you have Thread.Sleep() in other locations, they would need to be refactored.
If you have any other infinite loops using goto, those may need to be refactored as well.

LayoutSerializationCallback not be called

I'm using AvalonDock and I would serialize and deserialize my layout. But the callback (where I use the ContentId for create an instance of correct object) is not always called. For this reason the loaded not work correctly. I have tried to add one "try-catch", but not thrown exception.
This is my code:
` var layoutSerializer = new XmlLayoutSerializer(manager);
layoutSerializer.LayoutSerializationCallback += (s, e) =>
{
MyClass item;
if (items.TryGetValue(e.Model.ContentId, out item))
{
e.Content = item;
var tool = item as IMyClassToolApp;
var anchorable = e.Model as LayoutAnchorable;
var document = item as IMyClassDocumentApp;
var layoutDocument = e.Model as LayoutDocument;
if (tool != null && anchorable != null)
{
addToolCallback(tool);
tool.IsVisible = anchorable.IsVisible;
tool.IsSelected = e.Model.IsSelected;
return;
}
if (document != null && layoutDocument != null)
{
addDocumentCallback(document);
// Nasty hack to get around issue that occurs if documents are loaded from state,
// and more documents are opened programmatically.
layoutDocument.GetType().GetProperty("IsLastFocusedDocument").SetValue(layoutDocument, false, null);
document.IsVisible = true;
document.IsSelected = layoutDocument.IsSelected;
return;
}
}
e.Cancel = true;
};
try
{
layoutSerializer.Deserialize(stream);
}
catch
{
return false;
}`
Thank you for your help!
Are you sure your stream is O.K? If for example configuration file does not exist LayoutSerializationCallback method will not be called.
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
try
{
MainWindow.logger.Debug("Entering: {0}", "MainWindow_Loaded");
string filePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
#"Jofta\Analyzer\configs\AvalonDock.config");
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
XmlLayoutSerializer serializer = new XmlLayoutSerializer(this.dockingManager);
serializer.LayoutSerializationCallback += this.Serializer_LayoutSerializationCallback;
serializer.Deserialize(filePath);
}
MainWindow.logger.Debug("Exiting: {0}", "MainWindow_Loaded");
}
catch (Exception ex)
{
MainWindow.logger.Error("Exception in: {0}", "MainWindow_Loaded");
MainWindow.logger.Error("Message: {0}", ex.Message);
}
}
private void Serializer_LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)
{
try
{
MainWindow.logger.Debug("Entering: {0}", "serializer_LayoutSerializationCallback");
if (e.Model.ContentId == ObjectExplorerViewModel.AnchorableContentId)
{
e.Content = Workspace.Instance.ObjectExplorer;
return;
}
// ...
// ...
MainWindow.logger.Debug("Exiting: {0}", "serializer_LayoutSerializationCallback");
}
catch (Exception ex)
{
MainWindow.logger.Error("Exception in: {0}", "serializer_LayoutSerializationCallback");
MainWindow.logger.Error("Message: {0}", ex.Message);
}
}

FileSystem Watcher Firing multiple events

It seems like my file system watcher is firing mulitple events and then ending up giving me an error:
The process cannot access the file, file is in use.
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
// Form2 popup = new Form2();
if (Directory.Exists(this.textBox2.Text) && string.IsNullOrWhiteSpace(textBox2.Text))
{
MessageBox.Show("Please Select Source Folder");
return;
}
else if (Directory.Exists(this.textBox3.Text) && string.IsNullOrWhiteSpace(textBox3.Text))
{
MessageBox.Show("Please Select Destination Folder");
return;
}
else WatchFile();
private void WatchFile(/*string watch_folder*/)
{
FileSystemWatcher _watcher = new FileSystemWatcher();
_watcher.Path = textBox2.Text;
_watcher.NotifyFilter = NotifyFilters.LastWrite;
_watcher.Filter = "*.log";
_watcher.Changed += new FileSystemEventHandler(InitList);
_watcher.EnableRaisingEvents = true;
_watcher.IncludeSubdirectories = false;
listBox1.Items.Add("Started Monitoring Directory " + textBox2.Text);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
private object lockObject = new Object();
public void InitList(object source, FileSystemEventArgs f)
{
_recordList = new List<MyData>();
string fileName = f.FullPath;
string filePath = f.Name;
string trPath = fileName;
string[] arrstringPath = new string[3];
arrstringPath[0] = filePath.Substring(2, 2);
arrstringPath[1] = filePath.Substring(4, 2);
arrstringPath[2] = filePath.Substring(6, 2);
string tempPath = "LG" + arrstringPath[0] + arrstringPath[1] + arrstringPath[2] + ".001";
string v15nativePath = textBox3.Text + tempPath;
_watcher.EnableRaisingEvents = false;
if (!Monitor.TryEnter(lockObject))
{
return;
}
else
try
{
//_watcher.EnableRaisingEvents = false;
_watcher.Changed -= new FileSystemEventHandler(InitList);
FileStream trFS = new FileStream(trPath, FileMode.Open, FileAccess.Read);
StreamReader trSR = new StreamReader(trFS);
// FileStream v15FS = new FileStream(v15nativePath, FileMode.Open, FileAccess.Write);
StreamWriter v15SR = new StreamWriter(v15nativePath, false);
var timeIndex = "S";
Func<string, MyData> values = new Func<string, MyData>(
(x) =>
{
if ((x[0].ToString()) == "S")
{
var temptime = x.IndexOf("S");
timeIndex = x.Substring(temptime + 1, 4);
}
if ((x[0].ToString()) == "C")
{
var trackIndex = x.IndexOf(":");
var titleidString = x.Substring(11, 6);
var trackString = x.Substring(17, 40);
var trackDuration = x.Substring(57, 5);
return new MyData { Time = timeIndex, Duration = trackDuration, TitleID = titleidString, Track = trackString };
}
else
return null;
});
while (trSR.Peek() != -1)
{
var data = trSR.ReadLine();
MyData my = values(data);
if (my != null)
_recordList.Add(my);
}
trFS.Close();
trSR.Close();
var groupData = from data in _recordList
select new
{
Name = data.Track,
Duration = data.Duration,
Time = data.Time,
ID = data.TitleID
};
foreach (var item in groupData)
{
var newstringLen = item.Name.Truncate(27);
var v15timeString = item.Duration;
var v15fileString = "C" + item.Time + ":" + "00" + item.ID + " " + newstringLen + v15timeString;
v15SR.WriteLine(v15fileString);
v15SR.Flush();
}
v15SR.Close();
this.Invoke((MethodInvoker)delegate { listBox1.Items.Add(string.Format("File is Translated")); });
_watcher.Changed += new FileSystemEventHandler(InitList);
}
catch (Exception e)
{
//listBox1.Items.Add("The process failed: "+" "+e.ToString());.
MessageBox.Show("The Process Failed:" + e.ToString());
}
finally
{
Monitor.Exit(lockObject);
_watcher.Path = textBox2.Text;
_watcher.EnableRaisingEvents = true;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
I have called _watcher.EnableRaisingEvents = false; before the try block and then make it true in the final block yet. the watching get's disabled while I do the processing then why does it run the InitList method again after it finishes. This seems like a mulitple run on the same file, and so causing this exception

Background Worker Locking Main Thread - Windows Forms C#

I have a background worker that I use to create files in the background.
I had it working so that the files were created and the UI was still responsive.
I made some changes and now I can't figure out why the background worker is locking my main thread.
Here are my background worker methods. I don't have a progress changed event.
private void filecreator_bgw_DoWork(object sender, DoWorkEventArgs e)
{
if (filecreator_bgw.CancellationPending == true)
{
e.Cancel = true;
}
else
{
myManager.createFiles((SelectedFileTypes) e.Argument);
}
}
private void filecreator_bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
//status_label.Text = "Canceled!";
}
else if (e.Error != null)
{
//status_label.Text = "Error: " + e.Error.Message;
}
else
{
// Check the file manager object to see if the files were created successfully
status_label.Text = "COMPLETE";
file_statusLabel.Text = "Files Created: " + DateTime.Now.ToShortTimeString();
System.Threading.Thread.Sleep(5000);
status_label.Text = "Click Create Files to Begin";
createfiles_button.Enabled = true;
}
}
Here is the method to create the files.
public void createFiles(SelectedFileTypes x)
{
if (string.IsNullOrEmpty(Filename) || (x.isCSV == false && x.isTAB == false && x.isXML == false))
{
filesCreated = false;
return;
}
// Declare the streams and xml objects used to write to the output files
XDocument xmlFile;
StreamWriter swCSV;
StreamWriter swTAB;
CSVFilename = Path.GetDirectoryName(Filename) + Path.DirectorySeparatorChar.ToString() +
Path.GetFileNameWithoutExtension(Filename) + "CSV_TEST.csv";
swCSV = new StreamWriter(CSVFilename);
TABFilename = Path.GetDirectoryName(Filename) + Path.DirectorySeparatorChar.ToString() +
Path.GetFileNameWithoutExtension(Filename) + "TAB_TEST.csv";
swTAB = new StreamWriter(TABFilename);
XMLFilename = Path.GetDirectoryName(Filename) + Path.DirectorySeparatorChar.ToString() +
Path.GetFileNameWithoutExtension(Filename) + "XML_TEST.csv";
xmlFile = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("Crosswalk"));
xmlFile.Add(new XElement("ACCOUNTS"));
// String array for use when creating xml nodes
string[] splits;
// String used to read in a line from the input file
string line = "";
// Use a try and catch block, if any errors are caught, return false
try
{
// Read each line in the file and write to the output files
using (StreamReader sr = new StreamReader(Filename))
{
int i = 0;
while ((line = sr.ReadLine()) != null)
{
if (x.isCSV)
{
swCSV.WriteLine(line.Replace(delim, ","));
}
if (x.isTAB)
{
swTAB.WriteLine(line.Replace(delim, "\t"));
}
if (x.isXML)
{
if (i <= 0)
{
i++;
continue;
}
splits = line.Split(new string[] { delim }, StringSplitOptions.RemoveEmptyEntries);
xmlFile.Root.Add(
new XElement("ACCOUNTS",
from s in header
select new XElement(s, splits[Array.IndexOf(header, header.Where(z => z.Equals(s, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault())])
)
);
}
}
// Dispose of all objects
swCSV.Close();
swCSV.Dispose();
swTAB.Close();
swTAB.Dispose();
if (x.isXML)
{
//xmlFile.Save(Path.GetFullPath(Filename) + Path.GetFileNameWithoutExtension(Filename) + "_TEST.xml");
xmlFile.Save(XMLFilename);
}
}
}
catch (Exception)
{
filesCreated = false;
return;
}
// Return true if file creation was successfull
filesCreated = true;
}
In the do work method, I build a simple struct to determine what output file types should be made and then I pass it to the method. If I comment out that call to create the files, the UI still does not respond.
In the create files method, I build out the files based on the input file that I am transforming. I do use a LINQ statement to help build out XML tags, but the arrays holding the tags values are small, 3-5 elements depending on the file chosen.
Is there a simple solution, or should I re-design the method. If I have to re-design, what are things I should keep in mind to avoid locking the main thread.
Thanks
Here is how I call the runworkerasync method:
private void createfiles_button_Click(object sender, EventArgs e)
{
SelectedFileTypes selVal = new SelectedFileTypes();
foreach (var structVal in outputformats_checkedListBox.CheckedItems)
{
if (structVal.ToString().Equals("CSV", StringComparison.InvariantCultureIgnoreCase))
selVal.isCSV = true;
if (structVal.ToString().Equals("TAB", StringComparison.InvariantCultureIgnoreCase))
selVal.isTAB = true;
if (structVal.ToString().Equals("XML", StringComparison.InvariantCultureIgnoreCase))
selVal.isXML = true;
}
// Call the FileManager object's create files method
createfiles_button.Enabled = false;
filecreator_bgw.RunWorkerAsync(selVal);
}
UPDATE:
I updated the call to start the worker and then the call to create the files using the argument passed into the worker.
You cannot interact with most UI controls directly from a BackgroundWorker. You need to access outputformats_checkedListBox.CheckedItems from the UI thread and pass the resulting SelectedFileTypes object into the BackgroundWorker as a parameter.
Also, pleas enote that your cancellation logic really didn't do much. In order for it to work well, you need to check CancellationPending throughout the process, not just when starting.
Here is a rough example of how you should start the worker:
private void StartWorker()
{
SelectedFileTypes selVal = new SelectedFileTypes();
foreach (var structVal in outputformats_checkedListBox.CheckedItems)
{
if (structVal.ToString().Equals("CSV", StringComparison.InvariantCultureIgnoreCase))
selVal.isCSV = true;
if (structVal.ToString().Equals("TAB", StringComparison.InvariantCultureIgnoreCase))
selVal.isTAB = true;
if (structVal.ToString().Equals("XML", StringComparison.InvariantCultureIgnoreCase))
selVal.isXML = true;
}
filecreator_bgw.RunWorkerAsync(selVal);
}
private void filecreator_bgw_DoWork(object sender, DoWorkEventArgs e)
{
SelectedFileTypes selVal = (SelectedFileTypes)e.Argument;
myManager.createFiles(selVal);
}

Categories