I inherited an old VB.NET program that was written long before I got to this job. I'm having to rewrite it in C#. I have been unable to find anything that seems to be a conversion for this. Can someone show me a translation for this in C#, please?
Private Sub Log(Message As String)
Try
If txtLog.InvokeRequired Then
txtLog.Invoke(Sub()
Log(Message)
End Sub)
Else
txtLog.AppendText(Message & Environment.NewLine)
End If
Catch ex As Exception
End Try
End Sub
This is the code converted to C#:
private void Log(string Message)
{
try
{
if (txtLog.InvokeRequired == true)
{
txtLog.Invoke(() =>
{
Log(Message);
});
}
else
{
txtLog.AppendText(Message + Environment.NewLine);
}
}
catch { }
}
how can I write the following code written in c# to vb.net.
I am trying to write a finger print program but I got stuck to this point
what is the right way to do it?
public bool Connect_Net(string IPAdd, int Port)
{
if (objCZKEM.Connect_Net(IPAdd, Port))
{
//65535, 32767
if (objCZKEM.RegEvent(1, 32767))
{
// [ Register your events here ]
// [ Go through the _IZKEMEvents_Event class for a complete list of events
objCZKEM.OnConnected += ObjCZKEM_OnConnected;
objCZKEM.OnDisConnected += objCZKEM_OnDisConnected;
objCZKEM.OnEnrollFinger += ObjCZKEM_OnEnrollFinger;
objCZKEM.OnFinger += ObjCZKEM_OnFinger;
objCZKEM.OnAttTransactionEx += new _IZKEMEvents_OnAttTransactionExEventHandler(zkemClient_OnAttTransactionEx);
}
return true;
}
return false;
}
////////////////////////////////////////////
and here is the code I want to try to convert to:
<!-- language: vb.net -->
Public Function Connect_Net(ByVal IPAdd As String, ByVal Port As Integer) As Boolean
If objCZKEM.Connect_Net(IPAdd, Port) Then
If objCZKEM.RegEvent(1, 32767) Then
objCZKEM.OnConnected += AddressOf ObjCZKEM_OnConnected
objCZKEM.OnDisConnected += AddressOf objCZKEM_OnDisConnected
objCZKEM.OnEnrollFinger += AddressOf ObjCZKEM_OnEnrollFinger
objCZKEM.OnFinger += AddressOf ObjCZKEM_OnFinger
objCZKEM.OnAttTransactionEx += New _IZKEMEvents_OnAttTransactionExEventHandler(AddressOf zkemClient_OnAttTransactionEx)
End If
Return True
End If
Return False
End Function
''''''''''''''''''''''''''''
''''''''''''''''''''''''
But:
I get this error:
Error 4 Operator '+' is not defined for types 'Object' and
'Void'. C:\Users\PC50\Documents\Visual Studio
2010\Projects\Ref_Con\Ref_Con\Utilities\ZkemClient.vb
I have this code on different thread:
string sub = "";
this.BeginInvoke((Action)(delegate()
{
try
{
sub = LISTVIEW.Items[x].Text.Trim();
}
catch
{
}
}));
MessageBox.Show(sub);
what I want is to get the value of "LISTVIEW.Items[x].Text.Trim();" and pass it to "sub". please note that the LISTVIEW control is on the main thread. now how can I accomplish this?
enter code here
Func<string> foo = () =>
{
try
{
return LISTVIEW.Items[x].Text.Trim();
}
catch
{
// this is the diaper anti-pattern... fix it by adding logging and/or making the code in the try block not throw
return String.Empty;
}
};
var ar = this.BeginInvoke(foo);
string sub = (string)this.EndInvoke(ar);
You, of course, need to be a bit careful with EndInvoke because it can cause deadlocks.
if you prefer delegate syntax you can also change
this.BeginInvoke((Action)(delegate()
to
this.BeginInvoke((Func<String>)(delegate()
you stll need to return something from all branches and call end invoke.
I have a function that calls out a read or write request on a serial port and then returns the value that was read. I am using Commstudio express (I'm implementing a class from Commstudio) , but it's timeout features don't appear to work at all, so I'm trying to implement my own timeout. Currently I have a timer that is set upon request to read or write to the port, and if the timer goes off, the callback closes the connection causing an exception. I tried to have the callback of the timer throw an exception, but the exception needs to be propagated up through the thread that was calling the original read/write function, so in this way, it works, but I feel like it's messy and there must be a better way to do what I want.
Here is a generic solution that allows you to wrap any method in a timeout:
http://kossovsky.net/index.php/2009/07/csharp-how-to-limit-method-execution-time/
It uses the useful Thread.Join overload that accepts a timeout in milliseconds rather than manually using timers. The only thing I would do differently is swap the success flag and result value to match the TryParse pattern, as follows:
public static T Execute<T>(Func<T> func, int timeout)
{
T result;
TryExecute(func, timeout, out result);
return result;
}
public static bool TryExecute<T>(Func<T> func, int timeout, out T result)
{
var t = default(T);
var thread = new Thread(() => t = func());
thread.Start();
var completed = thread.Join(timeout);
if (!completed) thread.Abort();
result = t;
return completed;
}
And this is how you would use it:
var func = new Func<string>(() =>
{
Thread.Sleep(200);
return "success";
});
string result;
Debug.Assert(!TryExecute(func, 100, out result));
Debug.Assert(result == null);
Debug.Assert(TryExecute(func, 300, out result));
Debug.Assert(result == "success");
You could also add overloads that accept Action instead of Func if you want to execute a method that doesn't return a value.
Sounds like you're doing a blocking read/write. What you want to do is a non-blocking read/write.
There is probably a way to tell the com port that you're wanting non- blocking.
Are you sure the timeouts are not working with commstudio? maybe you have to do something special to initialise them.
In any case, you want to read as much data as possible and if none is available time out (depending on what the value of the time out is). You'll want to keep looping while no data available and no error and then return a time out condition if there wasn't anything available.
Make your read function return an integer. negative values = error value e.g. -1 = timeout, positive number of bytes read... at least thats the way I'd do it.
You can create an extension method that takes the Task<T> and a defaultValue of type T as input. Here is my implementation.
public static class Helpers
{
public static Task<T> SetTimeout<T>(this Task<T> task, T defaultValue, int timeoutInMilliseconds = 1000)
{
var timeout = Task.Delay(timeoutInMilliseconds);
Task.WaitAny(task, timeout);
if (!task.IsCompleted)
return Task.FromResult(defaultValue);
return task;
}
}
Here is a usage example:
var cars = await _myService.GetCars().SetTimeout(new List<string>() { "Toyota", "Nissan" });
For the comport you could just test if there is anything available and then do a read instead of doing a blocking read without knowing there is something yet. Something like:
Int32 timeout=1000;
String result = String.Empty';
while (timeout!=0) {
if (Serial.BytesToRead>0) {
while (Serial.BytesToRead>0) {
result+=Serial.ReadChar();
}
break;
}
Thread.Sleep(1);
timeout--;
}
In case someone wants to do this in VB.Net, don't listen to those who say it can't be done!
You may need to alter your generic parameters to suit your use case.
Public Shared Function Execute(Of I, R)(Func As Func(Of I, R), Input As I, TimeOut As Integer) As R
Dim Result As R
TryExecute(Func, Input, TimeOut, Result)
Return Result
End Function
Public Shared Function TryExecute(Of I, R)(Func As Func(Of I, R), Input As I, TimeOut As Integer, ByRef Result As R) As Boolean
Dim OutParam As R = Nothing
Dim Thread As New System.Threading.Thread(Sub() InlineAssignHelper(OutParam, Func(Input)))
Thread.IsBackground = True
Thread.Start()
Dim Completed As Boolean = Thread.Join(TimeOut)
If Not Completed Then Thread.Abort()
Result = OutParam
Return Completed
End Function
Private Shared Function InlineAssignHelper(Of T)(ByRef Target As T, ByVal Value As T) As T
Target = Value
Return Value
End Function
And an example of how to use it (mine was with Regex.Match, which sometimes goes off into never never land if the patterns contains too many wild cards:
Public Function Match(Input As String) As Match
If Regex Is Nothing Then Return Nothing
Dim RegexMatch As System.Text.RegularExpressions.Match = Nothing
Dim Func As New Func(Of String, System.Text.RegularExpressions.Match)(Function(x As String) Regex.Match(x))
If Runtime.TryExecute(Of String, System.Text.RegularExpressions.Match)(Func, Input, 2000, RegexMatch) Then
Return (New Match(Me, Regex.Match(Input), Input))
Else
Return Nothing
End If
End Function
Hey, how this is written in VB.NET? This was an example I found on http://www.codeproject.com/KB/silverlight/SynchronousSilverlight.aspx.
ThreadPool.QueueUserWorkItem(delegate
{
var channelFactory = new ChannelFactory<ISimpleService>("*");
var simpleService = channelFactory.CreateChannel();
var asyncResult = simpleService.BeginGetGreeting("Daniel", null, null);
string greeting = null;
try
{
greeting = simpleService.EndGetGreeting(asyncResult);
}
catch (Exception ex)
{
DisplayMessage(string.Format(
"Unable to communicate with server. {0} {1}",
ex.Message, ex.StackTrace));
}
DisplayGreeting(greeting);
});
May be a few syntax errors but I am sure you can resolve them.
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf GetGreeting))
Private Sub GetGreeting(o As Object)
Dim channelFactory = New ChannelFactory(Of ISimpleService)("*")
Dim simpleService = channelFactory.CreateChannel()
Dim asyncResult = simpleService.BeginGetGreeting("Daniel", Nothing, Nothing)
Dim greeting As String = Nothing
Begin Try
greeting = simpleService.EndGetGreeting(asyncResult)
Catch ex As Exception
DisplayMessage(String.Format("Unable to communicate with server. {0} {1}", ex.Message, ex.StackTrace))
End Try
DisplayGreeting(greeting)
End Sub
In VB10 (VS2010) you can do a rather literal translation:
ThreadPool.QueueUserWorkItem(
Sub()
Console.WriteLine("Hello")
End Sub)
And note that there are not linecontinuations (_) necessary here.
But you probably want this for VS2008 and then you need to break out the delegate as a separate Sub or Function.
Sub Main()
ThreadPool.QueueUserWorkItem(AddressOf CallBack, "Hello")
End Sub
Sub CallBack(ByVal state As Object)
Console.WriteLine(state)
End Sub
To provide a little explanation of the differences (other's have provided good code samples):
VB.NET doesn't support anonymous methods, which are supported in C# by using the delegate {} syntax to define an inline method. To convert that syntax to VB.NET you have to move the contents of the anonymous inline method out into a normal method, then use a Delegate pointed at the extracted method to initiate the call.
When both are compiled they are essentially the same, since anonymous methods in C# are really only anonymous in their pre-compiled state (the compiler generates names for the methods and then treats them as first-class methods).