Hi All,

On 22 Feb 2013, at 22:23, Jens Alfke wrote:


On Feb 22, 2013, at 8:32 AM, Dave <d...@looktowindward.com> wrote:

Of course there are threading "issues"!!!! Having delegates doesn't stop that

There are no threading issues if you don’t create background threads. I’ve written a lot of code that does network access using the async APIs, and most of it didn’t require me to create any background threads. Since all my code runs on the main thread, I don’t have any threading issues. That’s one less huge thing to worry about in my app.

I think I see what you mean, but I'd argue that there are still "threading" issues, the OS will create the Background Threads and take care of calling you back on the main thread, I agree, and, if that's all you were doing, it might be said to have "No Threading Issues", but, for instance, if the first ASync call, needs data to use on a later call, then there may well be "Threading Issues". Example 1:

Kick off ASync Operation A to get DataA.
Kick off ASync Operation B to get DataB.
Kick off ASync Operation C using DataA and DataB - You need to "worry" about "threading" (or at least the consequences of threading at this point).

In fact, I'd argue that using Sync on a user created Background thread would after a very small learning curve, actually result in less "Threading" issues but may well suffer performance wise. For instance in pseudo code, Example 1 would look something like:

-(void) driverProcess
{
[self doOperationA];
[self doOperationB];
}

-(void)doOperationA
{
[Network aSyncOperationAWithDelegate:@selector(handleOperationA)];
}

-(void)doOperationB
{
[Network aSyncOperationAWithDelegate:@selector(handleOperationB)];
}

-(void) handleOperationA:(DataA*) theDataA
{
if (xDataB == valid)
[Network aSyncOperationCWithData: theDataA andMoreDatax:DataB andDelegate:@selector(handleOperationB)];
}

-(void) handleOperationB:(DataB*) theDataB
{
if (xDataB == valid)
[Network aSyncOperationCWithData: xDataA andMoreData:theDataB andDelegate:@selector(handleOperationC)];
}

-(void) handleOperationC
{
}

xDataA and xDataB now need to be stored somewhere safe and also need to be checked for validity before use.

Whereas, if Sync is used:

-(void) driverProcess
{
DataA*                  myDataA;
DataB*                  myDataB;

if ([NSThread isMainThread] == YES)
        {
        [self performSelectorOnBackgroundThread:@selector(driverProcess)];
        return;
        }

myDataA = [Network syncOperationA];
myDataB = [Network syncOperationB];

[Network syncOperationCWithData: myDataA andMoreData:myDataB];
}

Less code and IMO, less "Threading Issues" but less performance.


Scalability is another issue that I don’t think anyone else has brought up — this is the reason that async network programming has become so popular in server frameworks like Twisted and Node.js. If you want to perform N simultaneous operations with a synchronous API, you have to spawn N threads. As N increases, this gets expensive: threads consume kernel resources and eat up address space for their stacks. With an async API, you can do the same work on a single thread. (And no, the OS does not create N threads behind your back to service the async API; it uses kqueues to manage any number of async tasks from a single background thread.)

Yes, I agree, but I'm not suggesting that ASync methods should never be used.

Example 1 above, may well be better run as an ASync operation.

But Example 2:

Kick off Sync Operation A to get DataA.
Kick off Sync Operation B Using DataA to get DataB.
Kick off Sync or ASync Operation C using DataB.

Is better as a Sync or mixed Operation.

Another example of where you might have to worry about threading using this method is if you have a large number of requests all replying at about the same time, in this case, the Main Thread is kept busy processing lots of small requests so that, although, it is not "Blocked" the UI becomes unresponsive and is actually worse than just "freezing with an activity indicator", since it leads the user to hit the same controls twice which put additional load on the system when it can cope least.

In this case, regardless of the method chosen (Sync vs Async) it would be better to handle updating the UI from one separate Background thread, thus creating "Threading Issues".


You don't have to take the example so literally! If I called the methods:

-(someValue) syncGetValueFromServer
{
//  Get Value From Server - takes a long time.
return Value;
}

-(void) aSyncGetValueFromServer:
{
//  Get Value From Server - takes a long time.
}

It would amount to exactly the same thing! You are making a common mistake of making conclusions about the method you are calling!

No, it wouldn’t be the same. The “aSyncGetValueFromServer” method would return immediately, letting me get on with other work on that thread. That’s what “asynchronous” means.

As long as the calling thread wasn't the main thread (which I already stated), the result on the system as a whole would be the same.

Surely, it depends on the implementation of the function/method? Just because a name has the word "ASync" it, doesn't automatically make it return almost immediately. My point really is that, from the point of view of the application programmer, making a call to a "Black Box" Library method, they not should be overly concerned with the implementation details, I agree, that this is not always possible in a less than ideal world (limited resources etc.), but I'm all for making it as concern free as possible. It seems to me that, people tend to assume that all Network activity should always use ASync methods, probably because of the restriction of making sure the Main Thread is never blocked. Other system don't have this restriction or concept of a Main Thread and so the mind set is different.

It also depends on what exactly the word "ASync" and "Sync" means to the developer writing the code. Given the choice of syncMethodX or aSyncMethodX, I for instance, would think, I need to spawn a Background Thread if I want to use Sync and not block the *Current* thread, not I'll use ASync because I'm running on the *Main* Thread.

Dave, it’s kind of rude to ask the list for advice/insight, then start yelling at us when you don’t like our opinions (especially when a lot of the people replying have a lot more Cocoa experience than you seem to.)

Who's yelling??? Not me and I've re-read what I wrote and I can't see anything "rude", and I wasn't really asking for advice, I was starting a discussion, that's why I put [OT] in the subject field.

Who that has replied to this message thread has more Cocoa experience and why would you say that from reading the messages posted on this subject?

Toodlepip
Dave


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to