Get and Set not being called - c#

So I have a couple fields in a program that set the email subject and email body for an automated message.
My Email Settings class is this:
public static class Email
{
public static string Body
{
get { return (string) SettingsStore.RetrieveSettingValue("emailBody"); }
set { SettingsStore.StoreSetting(new Setting {SettingKey = "emailBody",
SettingValue = value}); }
}
public static string Subject
{
get { return (string) SettingsStore.RetrieveSettingValue("emailSubject"); }
set { SettingsStore.StoreSetting(new Setting {SettingKey = "emailSubject",
SettingValue = value}); }
}
}
And my UI code that gets and sets the values is here:
private void ApplicationSettings_Load(object sender, EventArgs e)
{
subjectTextEdit.Text = Settings.Email.Subject;
bodyTextEdit.Text = Settings.Email.Body;
}
private void ApplicationSettings_FormClosing(object sender, FormClosingEventArgs e)
{
Settings.Email.Subject = subjectTextEdit.Text;
Settings.Email.Body = bodyTextEdit.Text;
}
Oddly, my get and set methods in the Email Settings class are not being called- when I access this form for the first time after application start the fields are blank even when the values are in the database. After I edit the fields once and close that form then open the form again (without closing the entire application) the fields have the text I put into them.
I have set a breakpoint on the _Load and _FormClosing events and these are getting hit.
When I set a breakpoint on the get/set methods inside the settings class, the breakpoints are not getting hit.
Any ideas?

To everyone: Thanks for your help, I found the issue- the issue was Visual Studio, not the code.
I closed VS, restarted the PC, opened VS, cleaned the solution, closed, reopened, built. There was an error in one of my referenced assemblies that was not appearing all the other times I built the project that appeared this time, and fixing that error caused all of this to work properly.
I'd have never found this without your help (I'd still be scratching my head wondering how my code was wrong) so thank you all so much! :)

Related

Xamarin iOS app freezes: ViewDidAppear() never gets called

This seems to be a tricky one:
We're working on a Xamarin iOS app that has a UITableView control displaying a list of profiles. Once the user clicks on one of the profiles we'd like to switch to a separate "ProfileViewController" to display more detailed information. This works just fine for 99.9% of the time. In the remaining ~0.1% the item in the list gets highlighted (which happens OnClick) but the app just seemingly freezes and never switches to the other ViewController, leaving the user with an unresponsive list.
The interesting thing to note here is that the app doesn't really freeze, as the simple "swipe back" gesture brings the user back to the UITableView (to be clear the switch-to-profile-viewcontroller animation is never played so it basically switches from the unresponsive list back to the same list, but now it is responsive again).
The tricky thing is that we can't reliably reproduce this bug. It just seems to happen at random, sometimes while stuff is running in the background, other times while the app was previously in an idle state. We are pretty sure that it isn't related to multithreading (we triple-checked everything, using locking and semaphores where necessary), it rather seems to be some rendering issue (as you can still swipe back to the previous screen or at least it isn't your common dead lock).
Using a bunch of Console.WriteLine() tracers and hours of trial and error reproducing this bug we could isolate the problem and discovered the following:
Upon clicking on the list code in ViewDidLoad() and ViewWillAppear() is successfully executed. However ViewDidAppear() never gets invoked. There is nothing else happening in our code or on different threads between ViewWillAppear() and ViewDidAppear() and we don't have any funky / unusual code that gets executed previously (just the usual UI initialization like this in ViewDidLoad()):
...
LblProfileName.TextAlignment = UITextAlignment.Center;
LblProfileName.Text = string.Empty;
LblProfileName.Font = FontAgent.ForSize(30);
LblProfileSlogan.TextAlignment = UITextAlignment.Center;
LblProfileSlogan.Text = string.Empty;
LblProfileSlogan.Font = FontAgent.ForSize(20);
LblProfileRelationInfo.TextAlignment = UITextAlignment.Center;
LblProfileRelationInfo.Text = string.Empty;
LblProfileRelationInfo.Font = FontAgent.ForSize(15);
...
At this point we are kinda out of ideas as to what could be going wrong here and we have independently reviewed any of our code that could remotely be involved in this bug but we found nothing.
We didn't find anything related online but maybe someone else has encountered a similar issue like this in Xamarin / Xamarin iOS before?
Are there any steps we could take that we don't know of? When breaking the app in the Visual Studio for Mac debugger during the freezes the call stacks only contain native code and are not of much use.
Any help or ideas as to what else we could try are hugely appreciated :)
Edit: Adding some code
This is our BaseViewController defining some initialization methods to be used by it's children (again in 99.9% of all cases this works just fine):
public abstract class BaseViewController : UIViewController
{
public BaseViewController(string nibName, NSBundle nSBundle) : base(nibName, nSBundle)
{
ControllerDidInitialize();
}
public ClubmappViewController(IntPtr handle) : base(handle)
{
ControllerDidInitialize();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
CustomOrientationService.ScreenRotationPortrait();
InitializeStaticContent();
Console.WriteLine("ViewDidLoad() exits just fine...");
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
Console.WriteLine("When the bug occurs this never gets executed :C");
RefreshUI();
OnViewDidAppear?.Invoke(this, new EventArgs());
LoadData();
}
private protected abstract void InitializeStaticContent();
private protected abstract void RefreshUI();
private protected virtual void LoadData()
{
}
private protected virtual void ControllerDidInitialize()
{
}
}
This is the ProfileViewController that inherits from BaseViewController and that just stops being rendered or inititialized or whatever the actual problem might be (it just never shows up as described above) but most of the time it works just fine:
public partial class ProfileViewController : BaseViewController
{
public const string STORYBOARD_ID = "ProfileViewController";
public ProfileViewController(IntPtr handle) : base(handle)
{
}
private protected override void ControllerDidInitialize()
{
// do initialization things like initializing variables, etc
// no real logic here
}
private protected override void InitializeStaticContent()
{
// layouting loading
LblProfileTitle.TextAlignment = UITextAlignment.Center;
LblProfileTitle.Text = string.Empty;
LblProfileTitle.Font = FontAgent.ForSize(20);
LblProfileTitle.Font = UIFont.BoldSystemFontOfSize(20);
LblProfileName.TextAlignment = UITextAlignment.Center;
LblProfileName.Text = string.Empty;
LblProfileName.Font = FontAgent.ForSize(30);
LblProfileSlogan.TextAlignment = UITextAlignment.Center;
LblProfileSlogan.Text = string.Empty;
LblProfileSlogan.Font = FontAgent.ForSize(20);
// ... and so on ..
}
private protected override void RefreshUI()
{
// ... theme related stuff ...
ViewProfileActive.BackgroundColor = ThemeAgent.CurrentTheme.OnlineIndicatorColor;
LblProfileName.TextColor = ThemeAgent.CurrentTheme.PrimaryTextColor;
LblProfileSlogan.TextColor = ThemeAgent.CurrentTheme.SecondaryTextColor;
// ...
}
private protected async override void LoadData()
{
// load user data ...
ProfileData data = await ...
}
}
And this is the "OnClick" event that is triggered when a profile is clicked on, that's supposed to initialize and show the ProfileViewController (it's unlikely that something's wrong with this but including it nonetheless):
// ...
(sender, e) =>
{
ProfileViewController profileController = (ProfileViewController)UIStoryboard.FromName("Main", null).InstantiateViewController(ProfileViewController.STORYBOARD_ID);
profileController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
currentViewController.NavigationController.PushViewController(profileController, true);
}
// ...

Visual Studio during Debugging: The function evaluation requires all threads to run

I'm suddenly getting a strange error while debugging. Up to now the variable in the watch windows has been showing correctly. Now I am always getting this error message in the watch windows:
The function evaluation requires all threads to run
I am not able to check any variable anymore. I am not explicitly working with threads. What can I do to get it working again?
I already disabled, as mentioned in some forums, the function: "Enable property Evaluation and other implicit function Calls" in the option window of the debugger. But without success, and it gives me this error:
Error Implicit Function evaluation disabled by the user
From the msdn forum:
This isn't an error in and of itself, but more of a feature of your debugger.
Some properties require code to be executed in order for the property to be read, but if this requires cross-thread interaction, then other threads may have to run as well. The debugger doesn't do this automatically, but certainly can, with your permission.
Just click the little evaluate icon and it will run your code and evaluate the property.
For further details on this behaviour check this excelent article
I ran into this issue when just trying to get items from a table called "AGENCY" using Entity Framework:
var agencies = db.AGENCY.OrderBy(e => e.FULLNAME);
Hovering over agencies in debug mode, clicking to expand the options, and clicking Results would give the dreaded "The function evaluation requires all threads to run" with a "Do Not Enter" icon at the end that, on which, clicking did nothing.
2 possible solutions:
Add .ToList() at the end:
var agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();
List<AGENCY_TABLE> agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();
Credit goes to Hp93 for helping me come to this solution. In the comments on MUG4N's answer where I found this solution, it also mentions trying .Any() instead of .ToList(), but this gives a Boolean instead of a <T>, like <AGENCY> is, so it probably wouldn't help.
Workaround - try a different path in the debug options. I found that I could click on the "Non-Public Members" > "_internalQuery" > ObjectQuery > Results View and get my values that way.
MUG4N has indeed provided a correct answer however if you hover over the line of code in debug, you may be looking at something like the below. If so, click the little re-evaluate icon highlighted in the image below...
NB: I obtained this image by pinning, normally the re-evaluate icone are in the middle of the window and not down the left hand column.
You should make thread safe call because accessing Windows form controls are not Thread safe in multithreading.
This is my simple code which makes Thread safe call and sets Progress bar.
public partial class Form1 : Form
{// This delegate enables asynchronous calls for setting
// the text property on a TextBox control.
delegate void StringArgReturningVoidDelegate(string text);
private Thread demoThread = null;
public int Progresscount = 0;
static EventWaitHandle waithandler = new AutoResetEvent(false);
public Form1()
{
InitializeComponent();
}
public static bool CheckForInternetConnection()
{
try
{
using (var client = new WebClient())
{
using (var stream = client.OpenRead("http://www.google.com"))
{
return true;
}
}
}
catch
{
return false;
}
}
public void Progressincrement()
{
waithandler.WaitOne();
while (CheckForInternetConnection()==true)
{
if (Progresscount==100)
{
break;
}
SetLabel("Connected");
Progresscount += 1;
SetProgress(Progresscount.ToString());
Thread.Sleep(TimeSpan.FromSeconds(1));
}
if (Progresscount <100)
{
Startthread();
}
SetLabel("Completed");
}
public void Startthread ()
{
this.demoThread= new Thread(new ThreadStart(Progressincrement));
this.demoThread.Start();
SetLabel("Waiting for connection");
while (CheckForInternetConnection() == false) ;
waithandler.Set();
}
private void SetLabel(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.label1.InvokeRequired)
{
StringArgReturningVoidDelegate d = new StringArgReturningVoidDelegate(SetLabel);
this.Invoke(d, new object[] { text });
}
else
{
this.label1.Text = text;
}
}
private void SetProgress(string Value)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.progressBar1.InvokeRequired)
{
StringArgReturningVoidDelegate d = new StringArgReturningVoidDelegate(SetProgress);
this.Invoke(d, new object[] {Value});
}
else
{
this.progressBar1.Value = Convert.ToInt32(Value);
}
}
private void Form1_Load(object sender, EventArgs e)
{
Startthread();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Responsive");
}
}
For more information MSDN
This isn't an error, but more of a feature of your debugger.
The debugger doesn't do this automatically, but certainly can, with users permission. Just click the little space icon and it will run the code and evaluate the property.
I use the next workaround to pass:
var OtherThreadField = "";
Invoke(new MethodInvoker(delegate
{
OtherThreadField = ExecuteNeededMEthod();
}));
Now i have a value for OtherThreadField.
I faced the same issue and solved .The Issue arise due to username and password ,in SQL connection there is user and password but in code there no user and password. so I enable the user and the password and the issue solved
For me, this happened when trying to break on a line that accesses a complex object instance contained by a Settings Class.
A breakpoint on the following if results in Settings.Default.FindSettings with the value being "The function evaluation requires all threads to run." If I press the force eval button, it is null. Stepping with the force eval button click or not enters the if block and initializes the object. If I remove the breakpoint and add a new breakpoint following the if block, the Settings.Default.FindSettings deserializes properly with the expected values.
if (Settings.Default.FindSettings == null)
{
Settings.Default.FindSettings = new FindSettings();
}
After trial and error, I added the following code before the above if block to access the settings prior to breaking. This seems to reliably fix the problem. I do not need it in production so I wrap in conditional compiler directive. I have a comment in the code instead of a non-descript discard:
#if DEBUG
var _ = Settings.Default.FindSettings;
#endif
I am not sure if the above line would be optimized out in production since it has side effects. As I only need it while debugging, I have not checked.

C# Settings.Default.Save() not saving? [duplicate]

This question already has answers here:
Why are my application settings not getting persisted?
(5 answers)
Closed 5 years ago.
this bug is pretty unusual. Basically my code will change the Settings.Default.Example then save and restart the program. Then when it loads, it shows a message box. However oddly, it shows a empty value when the form loads.
Here is my code:
Main.cs
private void Button1_Click(object sender, EventArgs e)
{
Settings.Default.Example = "Somevalue"; //Sets a value to the settings
Settings.Default.Save(); // Save it
MessageBox.Show(Settings.Default.Example); //Confirming it has been saved
Application.Restart();
}
private void Main_Load(object sender, EventArgs e)
{
MessageBox.Show(Settings.Default.Example); // Here is the weird part, it shows empty.
}
The MessageBox will show "Somevalue" when the button was clicked then the applcation restarts and the MessageBox that showed was empty. However repeating the process by clicking the button once more and restarting it does show the "Somevalue" MessageBox. Please help! Many Thanks!
Maybe you ran the same mistake as I did: setting the setting's scope to Application. Those kind of settings are not saved.
Set it to User to solve the problem.
rene is correct - you need to call Default.Reload after calling the Save method:
Settings.Default.Save();
Settings.Default.Reload();
Possibly a bug - ?
Posting as a reply to increase visibility -
If your AssemblyInfo.cs file has a * in Assembly Version then it's refreshing the file every build so you won't see persistence or reliability until you change that to a hard number and rebuild all, then retest everything.
After a full day of researching and studying the subject, I was able to solve this by putting the Configuration to the user:
Using System.Configuration;
Properties.Settings.Default.strinconn = txt_stringconn.Text;
Properties.Settings.Default.Save ();
Properties.Settings.Default.Upgrade ();
MessageBox.Show ("Saved Settings");
Application.Restart ();
Using Visual Studio 2013 - there is nothing I could do to make it work reliably, I would call Save and it did not save.
Save and then immediately Reload and it still would not retain the values on subsequent runs (probably related to when I stopped debugging could not identify the root cause) - very frustrating, likely there is an underlying bug but I cannot prove it.
To avoid getting crazy with this I decided to use the registry - the most fundamental way to keep app settings for an app.
Recommended for you all. Here is the code:
public static class RegistrySettings
{
private static RegistryKey baseRegistryKey = Registry.CurrentUser;
private static string _SubKey = string.Empty;
public static string SubRoot
{
set
{ _SubKey = value; }
}
public static string Read(string KeyName, string DefaultValue)
{
// Opening the registry key
RegistryKey rk = baseRegistryKey;
// Open a subKey as read-only
RegistryKey sk1 = rk.OpenSubKey(_SubKey);
// If the RegistrySubKey doesn't exist return default value
if (sk1 == null)
{
return DefaultValue;
}
else
{
try
{
// If the RegistryKey exists I get its value
// or null is returned.
return (string)sk1.GetValue(KeyName);
}
catch (Exception e)
{
ShowErrorMessage(e, String.Format("Reading registry {0}", KeyName.ToUpper()));
return null;
}
}
}
public static bool Write(string KeyName, object Value)
{
try
{
// Setting
RegistryKey rk = baseRegistryKey;
// I have to use CreateSubKey
// (create or open it if already exits),
// 'cause OpenSubKey open a subKey as read-only
RegistryKey sk1 = rk.CreateSubKey(_SubKey);
// Save the value
sk1.SetValue(KeyName, Value);
return true;
}
catch (Exception e)
{
ShowErrorMessage(e, String.Format("Writing registry {0}", KeyName.ToUpper()));
return false;
}
}
private static void ShowErrorMessage(Exception e, string Title)
{
if (ShowError == true)
MessageBox.Show(e.Message,
Title
, MessageBoxButtons.OK
, MessageBoxIcon.Error);
}
}
Usage:
private void LoadDefaults()
{
RegistrySettings.SubRoot = "Software\\Company\\App";
textBoxInputFile.Text = RegistrySettings.Read("InputFileName");
}
private void SaveDefaults()
{
RegistrySettings.SubRoot = "Software\\Company\\App";
RegistrySettings.Write("InputFileName", textBoxInputFile.Text);
}
Beware of calling
Settings.Default.Reload();
after each
Settings.Default.Save();
Save() function actually saves your changes to the file but it is not reflected to your running code. Thus, your code keeps the copy of the previous version of the file.
When you call Save() at another location in your code, it writes over your first change, effectively reverting your first change back to original value.
Very hard to pin down even when debugging.
Please have a look at this Question
Especially, try out the following code from an answer there:
using System.Configuration; // Add a reference to System.Configuration.dll
...
var path = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
Also, check out this overview, perhaps you ran into some limitation which is not easy to tell from your question.
This codeproject article might be of some help.
did you try calling ConfigurationManager.RefreshSection before checking that it got saved ad you could try it again after the reload
If you need to test your application how actually working in this case better to run the exe file. When you run on visual studio on debug mode when those settings saving it will take some time. Go to debug folder and run the exe you will get the messages as expected.
I had the same problem.
To sort out the problem.
Go to the custom class in Visual Studio.
Open the class and Check whether the constructor method.
If you have a constructor method, it should be parameterless.
If you have a constructor with parameters, don;t worry. Create another constructor class without an parameters.
Repeat this for all sub classes within the class.
Rebuild and run. Now your settings should save.

failed to update a static property

public static class clsCounter
{
static int count;
public static int Counter
{
get { return count; }
set { count = value; }
}
}
The above is the static class that is used to record a number.
Also, I have two projects within a VS2010 solution, one of which is a class library. In one of these classes, I have got the following code which uses clsCounter.
if (clsCounter.Counter == 0)
countIES++;
else
countIES = 0;
Now, in the other project, I set some new values to clsCounter
clsCounter.Counter = 50;
However, for some reason, I am not able to set clsCounter.Counter to 50, thus I always get countIES++. The code looks okay to me, and I have no idea what's wrong with it? Can anyone help?
Thanks.
EDIT:
I wonder if it has something to do with the scope of projects within vs solution?
Solution Structure
Solution
ExcelAddIn
Form1.cs => (clsCounter.Counter = 50)
...
ClassLibrary
clsCounter => (static class)
...
EDIT 2:
clsCounter.Counter = 50; is actually running in backgroundworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) event. Could this be a possible issue?
EDIT 3:
I have uploaded a sample project that seems to be able to reproduce the same problem. Here's the shared link: => http://www.4shared.com/folder/sInyNWyi/_online.html
What I would like to do here is to populate a cell with value, Other case after the button 'set value' is pressed. The static class and UDF can be found in the class library.
Note that, to be able to use =testFunc() within excel addin, need to find it in automation server list and enable it. So just go File->Option->Addin->Under Manage Add-in->Click GO->Automation->Ebale ClassLibrary1.UDF
Please also check if the option "Register for COM interop" has been enabled or not before launching the debugger. To find it, go ClassLibrary1 Property -> Build -> Under Output, check Register for COM interop.
Add the following line to your static property:
public static class clsCounter
{
private static int count;
public static int Counter
{
get {
Debug.WriteLine("Counter viewed");
return count;
}
set {
Debug.WriteLine("Counter Changed from {0} to {1}", count, value);
count = value;
}
}
}
Then you can watch your debugger and set breakpoints on the counter which will allow you to find out which part of the code is modifying your counter inappropriately. A static counter will be initialised "at some time" before it is accessed. I would say you are setting the counter and something somewhere is immediately incrementing it before you read it.
Finally, I think I found a workaround although it had nothing to do with the static. I was kinda inspired by the idea of using cookies in the web apps.
Similarly, all I need to do here is:
store a value in a temporary text file, by doing
System.IO.File.WriteAllText(#"C:\countIESValue.txt", value);
in the "set value" button click event handler.
And read the stored value whenever I need it from the above text file and assign it to a local variable.
if(System.IO.File.Exists(#"C:\countIESValue.txt"))
{
string val = System.IO.File.ReadAllText(#"C:\countIESValue.txt");
}
The text file can also be deleted after done processing. In this way, I don't have to worry about any scope or application domain issues, although the permission of writing files is required. I am glad it worked pretty all right for me.

Application settings do not allways save

I have a bit of a Heisenbug. I have a list of what was recently searched for sometimes it will save the history some times it does not. When I attach the debugger and step through StartFind() it works every time.
public Form1()
{
oldClinicsBindingSource.DataSource = ContractFlowTool.Properties.Settings.Default.RecentClinics;
}
private void StartFind()
{
(...)
if (oldClinicsBindingSource.Contains(newClinic))
oldClinicsBindingSource.Remove(newClinic);
oldClinicsBindingSource.Insert(0, newClinic);
oldClinicsBindingSource.EndEdit();
while (ContractFlowTool.Properties.Settings.Default.NumberOfClinicsToRemember < oldClinicsBindingSource.Count)
{
oldClinicsBindingSource.RemoveAt(oldClinicsBindingSource.Count - 1);
}
ContractFlowTool.Properties.Settings.Default.Save();
(..)
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{ //Breakpoint on this line
ContractFlowTool.Properties.Settings.Default.Save();
}
//In Settings.Designer.cs
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Collections.ArrayList RecentClinics {
get {
return ((global::System.Collections.ArrayList)(this["RecentClinics"]));
}
set {
this["RecentClinics"] = value;
}
}
If I put a breakpoint on the { before the save inside Form1_FormClosing then hit continue (I don't even step over) it saves correctly. If the breakpoint is not there it does not save.
The program does use background workers in other parts but they not being run in my test case case.
Any help would be greatly appreciated.
Commenting out the Save() inside StartFind() appears to have fixed it.
I am still curious why it was happening. Do binding sources use internal threading?

Categories

Resources