objects are not null and exception is still raised - c#

Answer: it was in the else code, but I thought there is no reason that code wouldn't point to that line.
Can someone offer an idea how it could be possible that I get "Object reference not set to an instance of an object" on this at Invoke method:
delegate void t(tabdescriptor tab);
internal void AddItem(tabdesciptor tab)
{
if (InvokeRequired)
{
t inv = new t(AddItem);
if (inv != null && tab!= null)
Invoke(inv, tab);
}
else
{
....
}
}

I'm not exactly sure what the actual issue is considering your example cannot be the code that executes, but please try something like this:
internal void AddItem(tabdesciptor tab)
{
if (InvokeRequired)
{
Invoke(new Action<tabdescriptor>(AddItem), tab);
}
else
{
//...
}
}
Also please make sure that it's not actually whatever is in the else part that fails.

If I remember correctly, this exception could be coming from inside the invoked method. If you place a try/catch inside the else of the AddItem method and a breakpoint inside the catch, do you catch the exception?
internal void AddItem(tabdesciptor tab)
{
if (InvokeRequired)
{
t inv = new t(AddItem);
if (inv != null && tab!= null)
Invoke(inv, tab);
}
else
{
try
{
....
}
catch
{
// breakpoint here
}
}
}

It's unclear whether it's a mistake in the given example, or not, but tab is never checked for null, yet it is passed as the argument.
Either it's probably null, or:
Also, inv is checked for null right after creating it (Good in C/C++, but unnecessary in C# as it throws an OutOfMemoryException upon failure), but it is done before checking o for null.

Related

How to exit a non void method in c#

I have a method that returns an ItemCollection, I want to stop the function early if there is no information provided. I would normally do this with a return; however as my method expects an ItemCollection it fails. I have this as a work around but it seems frankly hacky. Is there something I am missing. I tried just return; and I would prefer not throw an exception.
private ItemCollection loadLeft_Click(object sender, RoutedEventArgs e)
{
var leftUser = UsrLeft.Text;
if (leftUser == "")
{
MessageBox.Show("No User Entered");
GroupListLeft.Items.Add("");
var fail = GroupListLeft.Items;
return fail;
}
//Succesful test do stuff
var leftItems = GroupListLeft.Items;
return leftItems;
}
You have few options:
throw a new Exception (maybe even a custom one like NoUserEnteredException("someText")).
return null
return an empty collection or dummy object (see Null-object pattern)
The last one is better choice, in this case you don't need write a null-check or a try-catch section in client code.
You will need to return something that equates to an ItemCollection, depending on how you may want the calling procedures to handle such a return you could use a null return:
if (leftUser == "")
{
MessageBox.Show("No User Entered");
return null;
}
Or return a new ItemCollection e.g.
if (leftUser == "")
{
MessageBox.Show("No User Entered");
return new ItemCollection();
}
You will need to return null, like
private ItemCollection loadLeft_Click(object sender, RoutedEventArgs e)
{
var leftUser = UsrLeft.Text;
if (leftUser == "")
{
MessageBox.Show("No User Entered");
return null;
}
//Succesful test do stuff
var leftItems = GroupListLeft.Items;
return leftItems;
}
You can use "return null" which I do from time to time, but its not a good coding convention. Another option is to throw an exception and then catch it. Both is bad coding conventions and makes the code that uses this button add some rather obscure logic and dependencies.
From studying SOLID principles I would argue a better solution is to make a new type of object to return. f.ex. one that holds a list, but also a status message and then make it react a bit like when you have an HTTP request that depends on a success and otherwise cannot expect to have any content. This way, the object makes it clearer what to expect.
A fourth option, since this sounds UI related, is to possible have the click callback somehow and either update the collection, or update with an error message directly. But this might also be a bad coding convention that has impractical dependencies in the code.
Your code seems to return an object when you click on something.
(I am no expert in WPF, i don't know if this is possible).
I would encapsulate the function that returns the ItemCollection in a separate function and check whether the User is valid BEFORE calling this function.
This way you ensure that the ItemCollection is always valid (because you don't even try to retrieve it with an invalid user). Something like this:
private void loadLeft_Click(object sender, RoutedEventArgs e) {
var leftUser = UsrLeft.Text;
if(leftUser != "") {
ItemCollection coll = getItemCollectionForUser(leftUser);
}else {
//Error Handling
}
}
private ItemCollection getItemCollectionForUser(string user) {
//return ItemCollection here
}
Note how I wrote a separate function that returns the ItemCollection and the Click function returns nothing.

InvokeRequired to checkbox

I just need to create a function to checkbox that will return the current value of checkbox.
I wrote :
private void Checkbox_check()
{
if (checkBox1.InvokeRequired)
return (int)checkBox1.Invoke(new Func<int>(checked));
else
return checkBox1.Checked; // bad here i know
}
What is bad here, can someone just write correctly this function? I need Invoke because can't use in another Thread without invoke. I just search a forum and web about help but can't find solution anywhere.
Don't use Func<> as it doesn't return anything. Use Action instead.
private void Checkbox_check()
{
if (checkBox1.InvokeRequired)
checkBox1.Invoke(new Action(Checkbox_check));
else
{
// do what you like to do on the ui context
// checkBox1.Checked; // bad here i know, yep...
}
}
Getting the checked state from another thread, you could do like this:
private bool Checkbox_check()
{
// result value.
bool result = false;
// define a function which assigns the checkbox checked state to the result
var checkCheckBox = new Action(() => result = checkBox1.Checked);
// check if it should be invoked.
if (checkBox1.InvokeRequired)
checkBox1.Invoke(checkCheckBox);
else
checkCheckBox();
// return the result.
return result;
}
I would not advise this, this could lead to deadlocks etc. I advise you to pass the checked value on the threadstart, so you don't have to do any crossthread calls.
You should write it this way:
private void Checkbox_check()
{
if (checkBox1.Invoke:DRequired)
return (int)checkBox1.Invoke(new Func<int>(checked));
else
return checkBox1.Checked.(initInvoke);
}

Error : possible unintended reference comparison to get a value comparison cast the right hand

I have the following code which gives a warning "possible unintended reference comparison; to get a value comparison, cast the right hand side to type string":
// oControl is of type Control
if ((ocontrol.Name == oDataRowView["ConName"].ToString()))
{
//Do stuff
}
else
{
//Do other Stuff
}
I've tried to fix it using each of the following but I still get a warning
if ((ocontrol.Name == Convert.ToString(oDataRowView["ConName"])))
{
//Do stuff
}
else
{
//Do other Stuff
}
if ((ocontrol.Name == (string)oDataRowView["ConName"]))
{
//Do stuff
}
else
{
//Do other Stuff
}
Please could someone explain the reason I still get a warning and the best practice way to deal with this?
These options will work:
if (Equals(ocontrol.Name, oDataRowView["ConName"])) // likely best option
if ((string)ocontrol.Name == oDataRowView["ConName"].ToString()) // assuming neither item is null
if (ocontrol.Name as string == oDataRowView["ConName"] as string) // assuming second item is actually a string

Object reference not set to an instance of an object textBox

Hello i need a help with my code here
Im really confused about this error, i want to pass the value from textBox1 (form 1) to textBox7 (form 2).
and it said NullReferenceException was unhandled
Form 1
private void button1_Click(object sender, EventArgs e)
{
try
{
textBox1.Text = setIDtruk.getText;
this.Close();
}
catch(Exception)
{
MessageBox.Show("Wrong");
}
}
Form 2
public string getText
{
get
{
return textBox7.Text; // error in this statement
}
}
can anybody help me out ?
thanks
If you get a NullReferenceException on the line you indicate then the only reason that I can see is that testBox7 is null. We can't really tell you why it's null from the information that you've provided.
If it says NullReferenceException was unhandled it's probably because your TextBox7 is null.
You might need to go through your code and see where you missed a declaration.
If having a null TextBox is part of your code logic, in that case instead of returning the textBox7.Text directly, test it for null and if it is (null) return the appropriate value instead (like an empty string).

C# "ref" not Doing what I Think it Should

I have a class that talks to an external .exe. The class has a bunch of similar methods; they call a function of the .exe, wait for response, and then return true or false.
The response comes in the form of events that change the values of fields of this class.
Simplified code:
class Manager
{
private static bool connected = false;
public static bool Connect()
{
runtime.Connect();
int secondsWaited = 0;
while (!connected)
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}
return true;
}
}
The other methods use the same call-wait-loop-return structure.
My goal is to make a single method to do this waiting for me, like so:
private static bool WaitReferenceEqualsValue<T>(ref T reference, T value)
{
int secondsWaited = 0;
while (!reference.Equals(value))
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}
return true;
}
Then each method would do:
runtime.DoSomething();
return WaitReferenceEqualsValue<someType>(ref someField, someSuccessfulValue);
However, when I replace the wait-loop with this method call, the field "connected", even though passed in as a reference, always stays the same.
Any idea what's going on here, and how to get the desired functionality?
Thanks in advance.
EDIT:
public static bool Connect()
{
...
runtime.Connect();
// this code works
/*int secondsWaited = 0;
while (connected != true)
{
Thread.Sleep(1000);
if (secondsWaited++ == 10)
{
return false;
}
}*/
// this somehow blocks OnConnect from firing, so connected never gets set to true
lock (typeof(SkypeKitManager))
{
WaitReferenceEqualsValue<bool>(ref connected, true);
}
...
}
OnConnect:
private static void OnConnect(object sender, Events.OnConnectArgs e)
{
if (e != null && e.success)
{
lock (typeof(Manager))
{
connected = true;
}
}
}
You're not doing any synchronization on that field although you access it from multiple threads and one of them is writing. This is a race (no exception! this is a race even if it looks safe. It isn't safe.).
Probably the JIT enregistered it which is a common optimization. It just never gets read from memory, always from a register. Add synchronization (for example a lock, or Interlocked or Volatile methods).
Your usage of ref is correct.
The problem with your code is essentially compiler optimization. Fo optimization purpose compilers (or jits) necessarily take a pretty much single threaded view. The compiler/jit will then notice that you don't touch reference in your code at all, therefore it can move the comparison outside the loop. It is free to do so, since you basically create a race condition (no synchronization/atomic accesses).
Fixing it could either involve using synchronization mechanisms or add the volatile specifier to reference, thus telling the compiler/jit, that the variable can be changed from outside the method.

Categories