|
Seems to me that if your shell application is a singleton and cleans up when the children are closed then there should be no orphans.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
To be honest, it sounds to me like you need to investigate hosting each separate application in its own AppDomain. Just tear down the domain when the app needs to be unloaded. This Will also give you the ability to remove issues surrounding strange behaviour due to sharing the same assemblies.
|
|
|
|
|
I'm assuming you are referring to changing how the menu application loads the secondary apps. Unfortunately, I do not have any control over that code. And the last time I made a suggestion to change how the menu works, I got the distinct impression they felt I was attempting to pee in the office coffee pot.
|
|
|
|
|
SteveJD wrote: This has worked fairly well, except the dlls are never unloaded from memory...For example, performing a search in the first application instance updates the grids in all instances.
This is a design problem and not a dll problem.
Normally the only primary reason to unload a dll is because you need to load a new version of the dll without restarting the application.
Yours is problem in the design - probably because you are using singletons. Simple solution is don't use singletons. Each user has their own set of instances of the classes. There is no data overlap.
SteveJD wrote: I'm not up on all the latest design patterns
General consensus is that one shouldn't use Singletons...ever.
I wouldn't go that far as sometimes the appearance of a singleton can be an effective way to manage access to some resource. But there should be very few of them in the application and of course they would need to be usable by many threads at the same time (thus there could not be a problem as you are having.)
|
|
|
|
|
I am currently working on some settings for an application, but I have an annoying problem. I decided to store the settings in a .xml file and then read the values when loading the settings etc. Whenever the settings form is opened, the application will check the values stored in the .xml file and check a specific value is set to "true" or "false". I have a combobox and when you check this combobox, the application will ask you where you want to save the logs using FolderBrowserDialog. If you choose a folder then it will close, you can click the "Save" button and it will work. If you click on "Cancel" then the FolderBrowserDialog window will close and the checkbox will be unchecked automatically. The problem I am facing is that if you check the combobox, click the save button (which changes the value from "false" to "true"), exit the settings and then open the settings form then it will open the FolderBrowserDialog again. This is because the element, which in this case is called "<save_logs>", is set to true.
So my question to you is how can I fix this?
Combobox code
private void Save_log_CheckedChanged(object sender, EventArgs e)
{
if (Save_logs_checkbox.Checked && path_selected == false)
{
Save_logs_combobox.Enabled = true;
var fbd = new FolderBrowserDialog();
switch (fbd.ShowDialog())
{
case DialogResult.OK:
XmlHandler.Edit("//Other/Save_logs_path", fbd.SelectedPath);
path_selected = true;
break;
case DialogResult.Cancel:
Save_logs_checkbox.Checked = false;
Save_logs_combobox.Enabled = false;
break;
}
}
else if (Save_logs_checkbox.Checked && path_selected)
Save_logs_combobox.Enabled = true;
else
Save_logs_combobox.Enabled = false;
}
XML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Settings>
<Shortcuts>
<Copy_shortcuts>
<Shortcut_1>CTRL+ALT+1</Shortcut_1>
<Shortcut_2>CTRL+ALT+2</Shortcut_2>
<Shortcut_3>CTRL+ALT+3</Shortcut_3>
<Shortcut_4>CTRL+ALT+4</Shortcut_4>
<Shortcut_5>CTRL+ALT+5</Shortcut_5>
<Shortcut_6>CTRL+ALT+6</Shortcut_6>
<Shortcut_7>CTRL+ALT+7</Shortcut_7>
<Shortcut_8>CTRL+ALT+8</Shortcut_8>
<Shortcut_9>CTRL+ALT+9</Shortcut_9>
<Shortcut_10>CTRL+ALT+10</Shortcut_10>
</Copy_shortcuts>
<Paste_shortcuts>
<Shortcut_1>CTRL+SHIFT+1</Shortcut_1>
<Shortcut_2>CTRL+SHIFT+2</Shortcut_2>
<Shortcut_3>CTRL+SHIFT+3</Shortcut_3>
<Shortcut_4>CTRL+SHIFT+4</Shortcut_4>
<Shortcut_5>CTRL+SHIFT+5</Shortcut_5>
<Shortcut_6>CTRL+SHIFT+6</Shortcut_6>
<Shortcut_7>CTRL+SHIFT+7</Shortcut_7>
<Shortcut_8>CTRL+SHIFT+8</Shortcut_8>
<Shortcut_9>CTRL+SHIFT+9</Shortcut_9>
<Shortcut_10>CTRL+SHIFT+10</Shortcut_10>
</Paste_shortcuts>
<Other>
<Windows_start>false</Windows_start>
<Notifications>true</Notifications>
<Save_logs>false</Save_logs>
<Save_logs_path>C:\Users\UserHere\Desktop\Folder</Save_logs_path>
<Save_logs_as>txt</Save_logs_as>
</Other>
</Shortcuts>
</Settings>
|
|
|
|
|
You need a flag. It is only set when you change something about the log save location. Open the dialog when that flag is set. You never save the state of the flag and so it will not be set on form open and the dialog won't open. If you change the Saved Log location then set the flag and open the dialog.
Jack of all trades, master of none, though often times better than master of one.
|
|
|
|
|
Ron Nicholson wrote: You need a flag
Every time I see that I think of this[^].
|
|
|
|
|
I am afraid that I do not understand what you mean. Could you elaborate and/or perhaps give an example?
|
|
|
|
|
I've looked at your code again and I have a question.
if (Save_logs_checkbox.Checked && path_selected == false)
{
Save_logs_combobox.Enabled = true;
Apparently when this function is called, your path_selected is actually set to false. Is that true? If so then maybe you set path_selected to true before you set Save_logs_checkbox.checked to true.
All that said, I'd change the if statement to:
if ((Save_logs_checkbox.Checked) && (path_selected == false))
I just added the parentheses to make sure that it is being evaluated in the way you want it to be. Might be ok, but I like to sprinkle them around.
Jack of all trades, master of none, though often times better than master of one.
|
|
|
|
|
I would not ask for, and validate, a “log file folder name” (which should be displayed on the Settings form) until I did the “Save” for the settings. At that time, ask for a folder name if the corresponding checkbox is checked and the folder name is missing or invalid.
You could have a “Browse…” button (to get to the file dialog) that is enabled / disabled based on the “logging” checkbox.
(This is the usual “pattern” for an optional file / folder name … IMO).
|
|
|
|
|
I'm doing a project on securing biometrics. Where can I get a biometric application (that includes sample templates and also enrolments can be done)? I will then integrate the app in my C# project where I will be able to encrypt the templates.
|
|
|
|
|
|
Hi!
I wonder if this code is a correct way of using the IDisposable using keyword. Can I put the try-catch block inside it like this, and is it fine to insert a return inside the usage block? (the code is part of a method)
using(StreamReader reader = File.OpenText(fileName))
{
int lineIndex=0;
string line;
while((line=reader.ReadLine()) != null)
{
string[] fields = line.Split(';');
try
{
prodLst.Add(new Produkt(Int64.Parse(fields[0]), (ProdKategoriEnum)Int32.Parse(fields[1]), fields[2], Int32.Parse(fields[3]), Int32.Parse(fields[4])));
prodFileIndexDic.Add(Int64.Parse(fields[0]), lineIndex);
lineIndex++;
}
catch(FormatException e)
{
return false;
}
}
return true;
}
|
|
|
|
|
Entering a try..catch block is not free, in terms of overload. You may enclose your whole while loop in the try..catch block instead (you'll pay the overload only once).
And there's nothing wrong in returning a value inside the block; your StreamReader will be disposed anyway.
If you think it can be a problem, though, you just have to declare a boolean value before using statement, use it in place of your return statements in the using block, and return it at the end.
There are two kinds of people in the world: those who can extrapolate from incomplete data.
|
|
|
|
|
Yes, that's fine - just like a try...catch...finally block will always execute the code in the finally section, it doesn't matter how you exit the using block, the Dispose will still be called.
Personally, I'd probably put the try...catch around the whole loop just to look tidier, and put the return true outside the using so it's more obvious, but it doesn't make any real difference in practice.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Not as an answer to your question, phil.o and OriginalGriff already covered that - but since you're apparently interested to learn about good practice:
When simply returning false in case of an exception, you'll never know why exactly your code failed. You should either log the exception message (and possibly its stacktrace) to a logfile or reconsider if it's not even better to just let your exception "bubble up" - meaning, your method would simply be a void method: Continuation of program execution means all went well, otherwise the exception will also abort the execution of the calling code scope. This is in most cases the best approach and saves you from checking boolean success-return values "everywhere". Only catch an exception if you're going to do something with it: Logging and rethrowing it (potentially wrapped as an InnerException into a custom exception) or actually doing something to remedy the error so that the program can continue normally.
Recursion: see Recursion.
|
|
|
|
|
As an implementation note one should keep in mind that dispose (which happens with using) doesn't insure that exceptions cannot be thrown.
Which is fine if you don't mind if an exception occurs on that last closing brace but if you are trying to create a fail safe method then it is inappropriate.
One should also consider what the impact is to the business functionality. So for example in the given sample code if one successfully read the file but then the close fails (in the dispose) then does the application (business functionality) really care?
|
|
|
|
|
Ok guys, thanks for your help.
|
|
|
|
|
Message Closed
modified 24-Mar-15 18:15pm.
|
|
|
|
|
You should never catch the general "Exception" type, except in the entry point to your application where you simply log the exception and exit.
In the OP's code, the try..catch block isn't needed, since there are TryParse methods which won't throw an exception if the input is invalid.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Message Closed
modified 24-Mar-15 18:15pm.
|
|
|
|
|
Gerry Schmitz wrote: You have no idea what he has "higher up".
Doesn't matter - swallowing every exception "just-in-case" is still a bad idea.
Gerry Schmitz wrote: You also can't seem to tell the difference between "Parse" and "TryParse".
What?! I suggest you try reading my comments again.
Gerry Schmitz wrote: You should "never" shoot your mouth off before thinking.
Talking to yourself is the first sign of madness.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Message Closed
modified 24-Mar-15 18:15pm.
|
|
|
|
|
Which will throw an exception when the input cannot be parsed.
Which is why I suggested using TryParse , which doesn't throw an exception.
Which would then mean that he wouldn't need a try..catch block to catch the exception from the Parse method.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Message Removed
modified 24-Mar-15 18:15pm.
|
|
|
|