Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Does anyone here know a little C#

Status
Not open for further replies.

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I'm finally ditching VB6 as my PC interface RAD tool as I can't really get it to work on the new Windows platforms..

Now I can handle C# but I have a little trouble understanding "Delegates"... I know these are needed to interact between classes.... I also know that in C++ we used DDX to exchange data between modules..

I have run through every tutorial... I get things working BUT!!! I need a good understanding...

Senario:----

I have a text string arriving on the COM port.... "Hello world!".
I want to place this in the textbox on my form...

In VB6 I did this..

TextBox1.Text = MsComm1.Input

In C# ( and newer basics ) I receive a permissions error...

I need to set up a delegate ( friend function) to allow me access to the textbox outside its scope!!!

Can anyone explain ( in English ) the functionality of a delegate??? I need to understand this so I don't need to scour the internet for example code...
 
Hola Ian,

Could you reproduce the permission error here?
 
They're basically just function pointers. Read https://msdn.microsoft.com/en-us/library/ms173171.aspx

Is the "permissions error" actually a cross-thread access of UI component warning? This happens when you try to access one of the UI components on the form from a thread other than the main UI thread. A delegate may be used in this case to re-call the function in the UI thread... I can't tell from what you wrote.
 
dougy83 said:
Is the "permissions error" actually a cross-thread access of UI component warning?

Yep!! Its all the cross threading I don't get..... When I program in C++ I can access any component on a form.. I can't get my head around this aspect....

I really don't understand why Microsoft just assumes no-one does "lone" development any more... If I develop an application, I hate the idea that components that I make, I then cannot access...

Everything I read about this subject, doesn't cover the basic why's and wherefor's They give the typical ( never used) example and expect it to what we need!!

I will write a section of code and post it tonight!!
 
Well there's the main UI thread that runs the controls' events, and there's potentially other threads for certain asynchronous events, e.g. receiving data from a serial port (perhaps) or some event from a background task that's running.

Anyway, to set text in a textbox you simply invoke a function from within the main UI thread. You can use the following pattern to check if the invoke is required, and just call the same function again in the appropriate thread. The component you check against can be any component on the form (I assume).
Code:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (textBox1.InvokeRequired)
            {
                textBox1.BeginInvoke(new Action<object, System.IO.Ports.SerialDataReceivedEventArgs>(serialPort1_DataReceived), sender, e);
            }
            else
            {
                byte []buff = new byte[serialPort1.BytesToRead];
                serialPort1.Read(buff, 0, buff.Length);
                textBox1.Text = "New Data: " + BitConverter.ToString(buff);
            }
        }

EDIT: note: The generic Action<> class allows you to create delegates without having to explicitly declare/define them.
 
Last edited:
atferrari Sorry Hi!

dougy83 .. Thanks... I haven't seen that " Action<> " before... I'll read up on it... It basically looks like all I need is this simple delegate to get to where I want to be.... I take it, its the same in VB2012?
 
Action<> is handy, but not essential. Action is available in VB, but obviously the syntax is different; instead of Action<class1, class2>(func) you'll use Action(Of class1, Of class2)(func), I believe.
 
Last edited:
I believe Microsoft has free VC++ for download, so if you don't like C# you can always use C/C++.
 
I believe Microsoft has free VC++ for download, so if you don't like C# you can always use C/C++.
I do use C++.. But I used to like VB6 for RAD applications... C++ is too finiky for small test programs.. I feel that C# is a bit finiky too...

Lets say I'm simulating a GPS receiver... I can produce the output of a GPS unit in VB6 and cram it into Proteus..

I don't want to write a full blown application every time I need to simulate a component... VB6 was excellent for that purpose.. Trying to achieve the same agility from C++ was tedious... Baa Humbug!!
 
For test programs, I often use Console applications. It takes only few minutes to create one, you can interact with it, you can caputre the output if you want. You can even integrate it with your IDE. Say, in MPLAB it can output into the Output window.
 
I think you would need to see one of my applications for testing my systems. We are just finishing one of the better simulators. The complete crane has been modeled in Blender. I need to interface 3ds modles in VB6 to interact directly... I like the idea of a console app but for the purpose of simulating a crane, forklift or excavator, a graphical representation is much easier to work with..... At work I still use XP so it's not an issue, but at home I only have Windows 7 and 8
 
You can write console applications in C# too.

I'm not sure where VB6 is ever better than VB.NET or C#.
 
I'm not sure where VB6 is ever better than VB.NET or C#.

Just simplicity!! Its not really an OOP development platform... I know its dated so that's why I've re-taken up C# I used to play with .net some years back with the tinyCLR embedded systems.... I just need to get back into it!!
 
Ok!! I have been doing some research
I came across this piece of code..... At first it seemed nonsense, after debugging I see what the delegate (function pointer ) is doing....
C:
using System;
using System.IO;

namespace BoilerEventAppl
{

    // boiler class
    class Boiler
    {
        private int temp;
        private int pressure;
        public Boiler(int t, int p)
        {
            temp = t;
            pressure = p;
        }

        public int getTemp()
        {
            return temp;
        }
        public int getPressure()
        {
            return pressure;
        }
    }
    // event publisher
    class DelegateBoilerEvent
    {
        public delegate void BoilerLogHandler(string status);

        //Defining event based on the above delegate
        public event BoilerLogHandler BoilerEventLog;

        public void LogProcess()
        {
            string remarks = "O. K";
            Boiler b = new Boiler(100, 12);
            int t = b.getTemp();
            int p = b.getPressure();
            if (t > 150 || t < 80 || p < 12 || p > 15)
            {
                remarks = "Need Maintenance";
            }
            OnBoilerEventLog("Logging Info:\n");
            OnBoilerEventLog("Temperature " + t + "\nPressure: " + p);
            OnBoilerEventLog("\nMessage: " + remarks);
        }

        protected void OnBoilerEventLog(string message)
        {
            if (BoilerEventLog != null)
            {
                BoilerEventLog(message);
            }
        }
    }
    // this class keeps a provision for writing into the log file
    class BoilerInfoLogger
    {
        FileStream fs;
        StreamWriter sw;
        public BoilerInfoLogger(string filename)
        {
            fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
            sw = new StreamWriter(fs);
        }
        public void Logger(string info)
        {
            sw.WriteLine(info);
        }
        public void Close()
        {
            sw.Close();
            fs.Close();
        }
    }
    // The event subscriber
    public class RecordBoilerInfo
    {
        static void Logger(string info)
        {
            Console.WriteLine(info);
        }//end of Logger

        static void Main(string[] args)
        {
            BoilerInfoLogger filelog = new BoilerInfoLogger("d:\\boiler.txt");
            DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
            boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(Logger);
            boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
            boilerEvent.LogProcess();
            Console.ReadLine();
            filelog.Close();
        }//end of main

    }//end of RecordBoilerInfo
}
Correct me if I'm wrong....
We created a instance of BoilerInfoLogger called filelog..
We created a instance of DelegateBoilerEvent
We then created two function pointers.. One to filelog.logger and one to this.logger.

We now have cascaded two events when BoilerEventLog is called.. The first event contains a pointer to the Logger function in RecordBoilerInfo and the second pointer to the logger function in BoilerInfoLogger.

I had to debug it several times to see what's happening... The way I had it in my mind was totally opposite of what's happening...

I'm going to try a few problems of my own to see if it has really sunk in!!
 
Yes, what you said is right. Normally, registering events doesn't require creation of a new delegate:
Code:
            boilerEvent.BoilerEventLog+= Logger;
            boilerEvent.BoilerEventLog+= filelog.Logger;
is sufficient.
 
Ok!! Back on C# again....... I have to make a small HID C# program... I have tried this

https://github.com/MightyDevices/MightyHID.

I first used the DLL, but the reference was in error..... It was written for NET4 and I'm running 3.5.. So I downloaded the source for the DLL and it compiles fne ( The only reference I had to get rid of was "System.Theading.task" doesn't affect compilation so I seem ok!

When I use MighyHID.DLL the reference now works.... My issue... In the main program they create a "FileStream" instance with a buffer of 32 bytes.... Now my HID device has 64 so I edited any code to a 64 byte buffer..

When run FileStream.Write()... FileStream.Flush() and FileStream.Read().. All whinge of "Incorrect Parameters"

But checking through the code the parameters are great.... I have upped the buffer to 256 ( in case ) but the error is still there.... Any idea's

If you need screenshots I'll give them..... I could try using 2013 ( which I have at work) with the original DLL..
 
If you need screenshots I'll give them.....
Yes. Include the code around where the error is occurring and the actual error message while you're at it. I've never used MightyHID, but if you give some information, I might be able to help.
 
Ok! Here is the fault occurring when _FileSteam(data,0,data.length);

C# 2.jpg
Then if I decrease data.length by 1 it must work, but then wont' flush..
C# 1.jpg

If I rem out the flush then the program continues, but the read fails with _FileSteam.read(data).

Here is the Exception in detail..
C# 3.jpg

If you want the full code I can post it.... Remember that I had to remove "System.Threading.Tasks." as it was a bad reference.... When looking at the exception... It gets into threading before it fails....
 
HID requires buffer length to be exactly the "size of the input report + 1". The first byte in the buffer must be set to 0 prior to calling. Otherwise it won't work. The file read will copy the report into the buffer starting from the second byte.

I'm not sure C# call will convey all the parameters to the underlying "ReadFile" call exactly as you specify them. If not, you will need to call "ReadFile" directly.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top