Why are async callback socket methods usually static? (assume I understand static class, method and data objects). Would there be a fundamental design/logic error if one were to write a class using these as instance methods? Is there anything special that one should be careful to avoid?
-
What makes you believe that async callback socket methods are usually static? – dtb Sep 09 '10 at 15:59
-
1Maybe (hopefully in my case :-)) I'm wrong, but a quick Google search seems to demonstrate that at least most sample code seems to be static. – Jess Sep 09 '10 at 16:01
-
@Jess: A link (or twelve) would be helpful. I'm with @dtb. – Adam Robinson Sep 09 '10 at 16:02
-
1Additionally, C# and C++ are very different. You should specify which you're talking about. – Adam Robinson Sep 09 '10 at 16:52
-
One example is here (C# is under the VB tab about half way down the page): http://msdn.microsoft.com/en-us/library/bew39x2a(v=VS.71).aspx – Jess Sep 09 '10 at 17:18
-
I'm writing my current project in C#, but curious about C++ input as well. – Jess Sep 09 '10 at 17:30
-
1@Jess: You're going to get answers that are contradictory. There is no commonality between C# and C++ in this regard. If you wish to know about both, I would suggest posting an additional question. – Adam Robinson Sep 09 '10 at 18:17
3 Answers
There is no specific reason that they should be static. It all depends on your design.
If the callback needs to access members in the class then it can be declared as a instance member. However, you will need to make sure that you correctly syncronize the access to the instance members because the callback can be invoked concurrently from different threads.
I guess the examples you looked at all passed the required data through to the callback through the IAsyncResult.AsyncState
so did not require additional information from the class. If you can do this it can simplify your code, since you no longer need to worry about thread syncronization etc..
Update
Just to clarify, based on the comments it seems I should have beed more explicit. It is not that the static callback would be thread safe, but rather that in a design where the data required is passed to the callback and of course this data is not shared by other threads then locking is not required. And since the callback is passed all the data it requires, it does not need access to the class instance and can therefore be made static.

- 52,623
- 10
- 78
- 89
-
3There's nothing inherently safe about accessing static members from other threads. The same synchronization would need to occur. – Adam Robinson Sep 09 '10 at 16:51
-
@Adam, I should have been more clear. I was trying to say that when the data is passed to the callback and the callback does not need to access shared data then no locking is required. While accessing data in the class. – Chris Taylor Sep 09 '10 at 18:02
-
Perhaps my inexperience with C++ is showing, but in C# there would be no reason to believe that a static function would not be accessing shared static resources. – Adam Robinson Sep 09 '10 at 18:16
-
1@Adam, Still I am not being clear and I appologize. In this regard there is no difference between C# and C++. My point that I failed to communicate is that `when NOT accessing shared data` there would not be a need to lock. And in my explanation I tried to sketch a picture where the static method receives all its data (even the components of that data are not shared) via the AsyncState member. I am certain we are all on the same page, I have just muddied the water with a badly worded explanation. – Chris Taylor Sep 09 '10 at 18:26
-
Callback functions are usually static because you don't know what anything about the class that you are making a call back on.
In fact a class instance function usually carries the "this" pointer as a hidden first parameter.
See: http://www.drdobbs.com/184403375;jsessionid=P5JGJLQBDYGWBQE1GHOSKH4ATMY32JVN?pgno=2
Edit: Also see Why callback functions needs to be static when declared in class
At least in C++, a non-static method expects to receive this
as a hidden parameter. Since whatever's invoking it as a callback doesn't know that, it won't pass that extra parameter. If you did manage to invoke a non-static member function as a callback, anything that attempted to use member data (which would happen via this
) would (almost certainly) have major problems.
I'd guess C# is at least somewhat similar, though I haven't studied the details enough to know for sure. Regardless of language, the code needs to know what data to work with. The obvious difference is that C# also supports delegates, which are extremely useful for callbacks.
Edit: as to how to avoid this, at least in C++ it's fairly simple. You'd typically want to use a library like ACE, Boost ASIO, or POCO that shields you from most of the messy details. If you do some looking around, you can probably find at least a few dozen others as well. Oh, I should add that most of the application framework-style libraries (e.g., wxWidgets and Qt) include classes to shield you from most of the messy details as well. The obvious difference is that these tend to "take over" the design of the application in general (though, in fairness, I should add that ACE tends a bit toward the same).
Of course, people have written libraries for C# as well, but I haven't used any enough to make a meaningful recommendation about them. A lot here also depends on the level of abstraction you're looking for. WCF (for example) does quite a bit more than just shield you from the messy details. Rather, it builds essentially its own complete idea of how to work with networks, that happens to (somewhere in there) be able to use sockets -- but for the most part, you're not really working with sockets anymore, you're working with WCF, which happens to use sockets.
Ultimately, however, the library is just hiding, not changing, what really happens. Somewhere inside the library, Winsock makes a callback to either a static member function or a free function that uses the basic C calling convention that it expects. That function then uses extra data (usually the parameter that's passed to it) to figure out what to invoke from there. What varies is how thick a layer of "insulation" there is between your code and the callback from Winsock.

- 476,176
- 80
- 629
- 1,111
-
You are talking here about C callbacks. C++ is different, you have to pass pointer to the method that will be invoked on a class instance. If library doesn't provide that, this callback should be exposed to the user as a functor or interface (observer, for example). Otherwise this is a very bad C-style minimalistic library that is hard to use and you will end-up writing a lot of code or at least wrap callbacks with something more useful. – Sep 09 '10 at 16:14
-
@Vlad: did you bother reading the question? He's not asking if that's the only way to do things, but asking *why* the code he's seen is written that way. Yes, there are libraries that shield you from that, but they typically work as he describes: invoke a static member function (or free function), that uses other data to invoke what you've asked for. – Jerry Coffin Sep 09 '10 at 16:22
-
2C# delegates (function pointers, basically, though slightly more than that) do not suffer from the same limitation. Delegates that point to instance methods are syntactically identical to delegates that point to static methods. Whether the delegate stays entirely inside managed code or is marshaled into unmanaged code, the .NET runtime (CLR) handles the instance-vs-static distinction transparently. – Adam Robinson Sep 09 '10 at 16:56