Return string after timeout in VB.NET - vb.net

I use the following function to send commands to an instrument and receive the query results back and it works fine.
Public Function InstrSndRcv(cmd2Send As String) As String
MyInstrument.WriteLine(cmd2Send)
' if myTimeout(desierdtime) then
'Return "my string"
'else
Dim qryRetrn As String = MyInstrument.ReadLine()
Return qryRetrn
'End if
End Function
I have commented out the conditional functionality I need in terms of a subroutine myTimeout(desiredtime). How to implement it in VB.NET?
The idea is to return "my string" in case the instrument does not respond to a query command. May be there is a better way to do this...

Related

I am using a method with a stored procedure, but it's always returning false

I am using bool method with Visual Studio 2015 and SQL Server 2005.
When I am passing correct details and click loginButton, the code always returns false from the stored procedure.
This is my stored procedure in SQL Server 2005:
ALTER PROCEDURE [dbo].[UserCheckLoginDetails]
(#IsLoginIdCorrect BIT OUTPUT,
#IsPasswordCorrect BIT OUTPUT,
#LoginID NVARCHAR(200),
#Password NVARCHAR(20)
)
AS
BEGIN
SET #IsLoginIdCorrect = 0
SET #IsPasswordCorrect = 0
IF EXISTS (SELECT * FROM UserInfo
WHERE loginid = #LoginID AND password = #Password)
BEGIN
SET #IsLoginIdCorrect = 1
SET #IsPasswordCorrect = 1
END
ELSE
IF EXISTS (SELECT * FROM UserInfo WHERE loginid = #LoginID)
BEGIN
SET #IsLoginIdCorrect = 1
END
END
This is my method returning True or False:
Private Sub GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean)
Using Conn As New SqlConnection(_SqlCon)
Using cmd As New SqlCommand("UserCheckLoginDetails", Conn)
cmd.CommandType = CommandType.StoredProcedure
Conn.Open()
'OutPut Parameters
cmd.Parameters.Add("#IsLoginIdCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output
cmd.Parameters.Add("#IsPasswordCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output
'InPut Parameters
cmd.Parameters.AddWithValue("#LoginID", LoginIDTextBox.Text)
cmd.Parameters.AddWithValue("#Password", PasswordTextBox.Text)
cmd.ExecuteNonQuery()
' Assign Parameters
IsLoginIdCorrect = Convert.ToBoolean(cmd.Parameters("#IsLoginIdCorrect").Value)
IsPasswordCorrect = Convert.ToBoolean(cmd.Parameters("#IsPasswordCorrect").Value)
End Using
End Using
End Sub
This is the Login button click event handler, even when I provide the correct values, it still always returns false:
Private Sub LoginButton_Click(sender As Object, e As EventArgs) Handles LoginButton.Click
Try
Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)
If IsLoginIdCorrect And IsPasswordCorrect = True Then
Me.Hide()
' User Information
DeshBoard.MainUserIdLabel.Text = Me.MainUserIdLabel.Text
DeshBoard.UserNameLabel.Text = Me.UserNameLabel.Text
DeshBoard.UserLoginIdLabel.Text = Me.UserLoginIdLabel.Text
DeshBoard.UserLevelLabel.Text = Me.UserLevelLabel.Text
'Organanization Information
DeshBoard.MainOrgIDLabel.Text = Me.MainOrgIDLabel.Text
DeshBoard.OrgNameLabel.Text = Me.OrgNameLabel.Text
DeshBoard.OrgTelLabel.Text = Me.OrgTelLabel.Text
DeshBoard.OrgEmailLabel.Text = Me.OrgEmailLabel.Text
DeshBoard.OrgAddressLabel.Text = Me.OrgAddressLabel.Text
DeshBoard.Show()
Else
If IsLoginIdCorrect = False Then
MessageBox.Show("Login ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
LoginIDTextBox.Clear()
PasswordTextBox.Clear()
LoginIDTextBox.Focus()
Else
MessageBox.Show("Password ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
PasswordTextBox.Clear()
PasswordTextBox.Focus()
End If
End If
Catch ex As ApplicationException
MessageBox.Show("Error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Thank you very much.
You need to add ByRef to both arguments in Sub GetIsUserLoginCorrect().
To demonstrate, try the following with and without ByRef.
Private Sub ChangeBoolean(ByRef TorF As Boolean)
TorF = True
End Sub
Private Sub OPCode2()
Dim TorF As Boolean
ChangeBoolean(TorF)
Debug.Print(TorF.ToString) ' Result False without ByRef in ChangeBoolean
'When ByRef is added result is True
End Sub
First off, a method can refer to either a sub or a function. A sub is a method that performs an action. A function is a method that calculates or retrieves one or more values.
A sub should not be called Getxxx, because its primary purpose should not be returning a value.
A function should be used to return values. Since you are trying to retrieve multiple values, if you were using 2017 I would suggest returning a named tuple with your two values, since you aren’t I would create an object that has the values and return that.
On a totally different note, you really can’t tell the difference between right user wrong password and wrong user right password and wrong user wrong password - so you shouldn’t tell someone you can. You just say login unsuccessful login, or invalid username/password combination.
There's a lot wrong with your code.
Firstly, why are you using so much of SQL code ? Correct me if i am wrong : You are trying to build a log in system. So much of SQL code or even the stored procedure is worthless here. You can simply write the SQL statements in your code by using the SqlCommand class. Even though you are using the ALTER PROCEDURE statement, i can surely say that things can be simplified here.
You are also using the Me keyword. It's not C# where the use of this(same as Me in VB.Net) becomes compulsory. I assume it's a Windows Forms Application and if that's so, then using Me keyword to access it's child elements wouldn't result in any different if it's not used at all.
The next worth mentioning issues is your Name Conventions. Most or should i say all of your variables have the same name. For example : IsLoginIdCorrect - used both as a parameter of a method and also a variable inside a method.
The next issues is in these two lies :
Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)
You are passing the boolean variables before they have been assigned any value. You are lucky it's not C# or this wouldn't even compile. Passing the boolean variables without assigning any value will, by default, set their values to False. So, literally, you are always passing the same value in which case, the outcome will always be the same.
The next issue is in your If statement inside your LoginButton_Click method aka LoginButton's click event handler's method :
If IsLoginIdCorrect And IsPasswordCorrect = True Then
The if statements, if described in simple words, means : If IsLoginIdCorrect and IsPasswordCorrect are true, then proceed.... So, in this case, IsPasswordCorrect = True doesn't affect much. However, this is not the best practice too. You should better follow the following coding rule while using If statements:
If (IsLoginIdCorrect = True AndAlso IsPasswordCorrect = True) Then
AndAlso operators evaluates each side just like the And operator. The difference is that it would return False if the left side(IsLoginIdCorrect, in this case) returns False.
The next issues is the usage of ApplicationException. I don't understand why, in this era, you are using that class! This class is usually used to derive from and create exceptions. You can simply use Exception instead of ApplicationException.
Your Try-Catch block seems not useful as well. All of your codes inside the LoginButton_Click are in If conditions and they perform very basic operation. It is unlikely to ever throw any exception at all.
Your logics, for most part, are illogical(sorry to put it this way). In your GetIsUserLoginCorrect method, you are setting IsLoginIdCorrect and IsPasswordCorrect to either true or false but it wouldn't matter because they are parameters of the method itself. So even if you set their values, they will be reset when you call the method again. The reason why ByRef (according to Mary's answer) works is because ByRef, in short, means that you are pointing to original variable that you passed(not it's copy).
And finally, the solution you are looking for....
Even though i see you have marked Mary's answer as the answer, i would like to help you out a bit as-well.
Firstly, get rid of the stored procedure if possible and also if you are not using it anywhere else. I see you are using the If Exist condition inside your SQL queries. This is actually a nice move because according to performance reports, checking if data exists in a database/table using IF EXISTS yields the fastest output. So bravo for that one. But if you follow my advice and want to ditch the stored procedure, then you need to get rid of the IF EXISTS statement as well. Rather, you can simply use the SELECT statement itself, use the ExecuteScalar method of the SqlCommand class, convert it's value to Integer and check if the value of the Integer is 1 or not.
Example :
Dim cmd = New SqlCommand("SELECT COUNT(*) FROM UserInfo
WHERE loginid = #LoginID AND password = #Password")
Dim Exists = Convert.ToInt32(cmd.ExecuteScalar)
If Exists = 1 Then
''Code if data exists
End if
Note that i have used Convert.ToInt32 here. This will prevent null-reference exception as when ExecuteScalar returns Null, it will be converted to 0 integer value.
Also, why are you using GetIsUserLoginCorrect as method ? You can simply use it as a function and return required values. As you are returning multiple values, you can easily use the Tuple type as your function's type:
Private Function GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean) As Tuple(of Boolean, Boolean)
....
....
return Tuple.Create(IsLoginIdCorrect, IsPasswordCorrect)
End Sub
Usage
Dim IsLoginCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item1
Dim IsPasswordCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item2
One last thing. As you are showing DeshBoard form after hiding the main form, make sure to call MainForm.Close on the Dashboard form's Closing/Closed event. This will ensure the application's exit(unless you have other plans for the main form, of course).
Hope this answer helps you.

Conversion From String to Boolean Vb.net

I want to evaluate a String with Boolean Values and Binary Logical Operators (And/Or).
When i write Dim Expression = ((True And False) Or True) then the value of "Expression" Will be true.
However, when i write Dim Expression = "((True And False) Or True)" and try to convert the string to Boolean using Convert.ToBoolean() like MsgBox(Convert.ToBoolean(Expression)) then i got an error stating: String was not recognized as a valid Boolean. as in the picture.
All previous posts deals with strings containing only "True" or "False". but rarely i found a post dealing with an Expression containing brackets and more than one operator as "((True Or False) And True)" or much more complicated expressions. is this supported in the convert.ToBoolean function and if yes why i am getting this error?
There is a round-about way of evaluating an expression using Microsoft script control ..
Right click on your project and choose Add
In the sub menu, choose Reference
In the window that appears, on the left click on COM
Scroll down until you see MicrosoftScriptControl 1.0 and double click it.
Then click Ok on the lower right of the window
This function takes a string and using VBScript, evaluates the string expression. You can of course tweak it to your needs.
Private Function EvaluateBoolean(formula As String) As Boolean
Dim sc As New MSScriptControl.ScriptControl
'SET LANGUAGE TO VBSCRIPT
sc.Language = "VBSCRIPT"
'ATTEMPT MATH
Try
Return Convert.ToBoolean(sc.Eval(formula))
Catch ex As Exception
'SHOW THAT IT WAS INVALID
MessageBox.Show("Invalid Boolean expression")
End Try
End Function

RunCode does not Run a Public Function in MS Access

I am new to MS Access and I am trying to create a simple Macro with a call to VBA code.
the VBA code here is a sample (which also doesn't run)
Public Function RunImport()
Dim N As Integer
Dim Message1, Message2, Title, Default1, Default2, JulianSD, JulianED
Message1 = "Enter Julian Start Date"
Message2 = "Enter Julian End Date"
Title = "User Input Section"
Default1 = "17365"
Default2 = "17000"
JulianSD = InputBox(Message1, Title, Default1)
JulianED = InputBox(Message2, Title, Default2)
End Function
do you think you might be able to locate an issue here?
Thanks!
PS. I am using Version 14.0.7177.500 (32-bit). it wasn't my choice.. (if it were, I wouldn't be using access.. :p)
The most common use of a function is to return a value or values. Your function does not appear to be returning any value. At the end of a function you would normally have a line of code that says what value the function will return, for example....
RunImport = JulianSD - JulianED
End Function
A line like this would usually be inserted before the 'End Function' line. However if your intention is not to return a value, but instead you just want to run a vba macro, perhaps you need to change your function to a Sub routine...
Public Sub RunImport()
'code goes here
End Sub

Call Function when User Types Certain Keyword

Okay, so I am working on a small scripting language using a VB Console Application.
I want the user to input "say('something')" and it calls the function I made named "say", is there a way to call the function and still use the following code:
Module Module1
Sub say(sayline)
Console.WriteLine(sayline)
End Sub
Sub Main()
Dim cmd As String
Console.WriteLine(">")
Do
Console.Write("")
cmd = Console.ReadLine()
If cmd IsNot Nothing Then cmd
Loop While cmd IsNot Nothing
End Sub
End Module
No, you cannot just call a method from user's string. You need to interpret the entered data.
First, you need to split your method name and arguments so that entered "say('something')" will transform to say and something. Remember that user can enter wrong data and you need to check if this call is correct - it's all about syntactic and lexical analysis. I hope you understand how to do this because it is pretty difficult.
Then, you need to check if you have a method called say. In case of plain and simple structure, switch construction will be enough. If your have such method, then pass something argument to this method. Else, output something like "unknown method".
If you wanted to call the method say upon typing the word say(something) and display the word something, then you can just have a certain condition that if the user types the word say within the input then call say method else, do whatever you want to do under else portion. Parse the input and omit the word say from the input and display it then.
You can have your code this way for example. (I just copied your code and added some codes to meet what you wanted... in my understanding)
Module Module1
Sub say(ByVal sayline)
Console.WriteLine(sayline)
End Sub
Sub Main()
Dim cmd As String
Do
Console.Write("> ")
cmd = Console.ReadLine()
Try
If cmd IsNot Nothing And cmd.Substring(0, 3).ToUpper().Equals("SAY") Then
say(parseInput(cmd))
End If
Catch ex As Exception
Console.WriteLine("message here")
End Try
Loop While cmd IsNot Nothing
End Sub
Function parseInput(ByVal cmd As String) As String
Dim input As String = ""
For index As Integer = 3 To cmd.Length - 1
If Char.IsLetter(cmd) Then
input += cmd.Substring(index, 1)
Else
input = input
End If
Next
Return input
End Function
End Module

Is this a thread safe code?

i have three functions in a module that several threads would be using. all of the functions access local variable except the main doWork sub.
Sub DoWork(byval i as integer)
synclock (ListTasks)
dim strItem as string =ListTasks(CInt(i)).ToString
end SyncLock
dim strHtml as string = GetHtml(strItem )
dim strParsed as string = ParseHtml(strHtml)
dim strResult as string = Report(strParsed )
End sub
Function GetHtml(byval url as string) as string
'code to get website
ens sub
Function ParseHtml(Byval html as string) as string
'code to parse HtmlString
end function
Function Report(Byval html as string) as string
'do the work
end function
Is this a thread safe code, so that no thread will overwrite data?
If each function are all using local variables (within the functions, each function is stateless and do not access any shared resources) and all the parameters are passed by value, so that its a separate copy in the stack ( not a reference to another object), it should be threadsafe and you really do not need any locking.
It looks like pretty much everything you're using is a local variable. Your also passing variables by value, not by reference, which helps for thread safety. So you appear to be pretty safe! Just make sure the one lock your using doesn't get you into a race condition.