Click here to Skip to main content
15,895,084 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi.

I have my application which has a Server class that is started from my main Form class, and it creates a socket (Async) listening to a specific port for data.

Now, I use an Asyn call back on the Server class that triggers when data is detected, and I would like my main GUI to update a status text to say "data received" but I have not got a clue how to send text back to the main GUI.

Any pointers please? I have googled and found that Delegates may be the answer but it seems so complex?

Thanks

What I have tried:

Any pointers please? I have googled and found that Delegates may be the answer but it seems so complex?

Thanks
Posted
Updated 29-Sep-17 13:37pm

1 solution

The background threads concept in .NET framework is so much confusing, and sometimes irrelevant to what you might actually be doing.

If I had to write this sort of application in today's version, I would choose async/await sort of programming, instead of the delegates way, because,

1. Delegates are tough to understand and properly program.
2. Delegates have other things to be handled as well; callbacks etc.
3. .NET has async/await, that are meant to replace the asynchronous programming with delegates and begin/end functions.

However, the concept of async/await will be simpler in this case. Because of the fact, that you will leave majority of the asynchronous programming to the framework itself. Also, .NET framework has several Async functions that return Task objects. We can use them and program our apps asynchronously. Something like this,

C#
public MainForm() {

    // Call to start the server here.
    startServer();
}

private void startServer() {
    server = new TcpListener(); // Pass your values

    // You need to rewrite this, it is just off the top of my head
    // Maybe taking this inside the listen function, and running a 
    // while(true) loop would be a better approach; but try either and chose.
    while(true) { 
        listen();
    }
}

private async void listen() { 
    // This will asynchronously listen
    var client = await server.AcceptTcpClientAsync(); 

    // Client was captured
    label.Text = "Client Connected";
    // Continue
}

The reason I am suggesting async/await instead of delegates is the simplicity and other features; less resources are consumed in async/await because there is just one thread doing all unless you specify to use more.

Oh, right, you can also modify this to work with the Socket class, I feel TCP specific class to be more simpler and handier. :-)

TcpListener Class (System.Net.Sockets)[^]

One more thing, you do not need to handle the Dispatcher or invocation here, because in the async/await code, only one thread is accessing resources, thus no need to load the UI update code back to the dispatcher pump.

Update

I can think of multiple ways of sending and updating the text on the main form, two of them are,

1) Create a static label field in the form, and set that to the label which you want to update, then use that field from the server class.
C#
public class MainForm {
    public static Label MyLabel { get; set; }

    public MainForm() {
        // Other constructor code
        MyLabel = this.label1;
    }
}

// Somewhere in the server code, 
public void listen() {
    // your server code, 
    MainForm.MyLabel.Text = "Updated text";
}

// Or you can have a separate function that updates the field, 
public void updateLabel (string message) {
    MainForm.MyLabel.Text = message;
}


2) The other way is to pass a reference of your current MainForm, to the server class so that server can use that object and update its values. This is somewhat ambiguous approach so I will not recommend, but just so that you know,

C#
public class Server {
    public static MainFrom parentForm { get; set; } // Can be instance as well
    public Server(MainForm referenceForm) {
       parentForm = referenceForm;
    }

    // Then update
    public void updateField(string message) {
        parentForm.label1.Text = message;
    }
}


And of course, you can have other ways as well. They all work quite similar, you need to pass the reference and then through that reference.
 
Share this answer
 
v2
Comments
Member 13164579 30-Sep-17 6:50am    
Hi Afzaal. Thank you for this solution but I think I have not explained myself correctly. Actually, I am using the above for my server but this is not quite what I am trying to find out, I was very tired when I wrote my question so I will try to explain better.

I have a main Form application and on it I have a button to start my server. I have a server class CServer.cs.

In my main form application I create a static member of my server class, and when the start button is clicked I trigger my Async method in my server class which starts listening on a UDP port. All of this works fine.

Now, on my main form I have a status bar and I would like to update the text from my server class/object but this is what I am struggling with.

Obviously I can update the text just fine in my main Form app, however, I want to send a number of different status messages back to the main form from within the server class.

I did try to google but I don't really know what I am looking for so it is hard to find a solution.

Thank you again
Afzaal Ahmad Zeeshan 30-Sep-17 11:16am    
Oh, okay.

Since the server is in a different class, then you need to pass back a reference to the server class, which will then use an update the text.

Please see the update in the answer above.
Member 13164579 30-Sep-17 14:15pm    
Perfect. Thank you Afzaal, much appreciated.

Kind regards

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900