Async NSURLConnection in iOS

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    dispatch_semaphore_t sem;
    NSMutableData *alldata;
}

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    sem = dispatch_semaphore_create(0);
    alldata = [[NSMutableData alloc] init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    
    [alldata appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    dispatch_semaphore_signal(sem);
}

- (IBAction)clicked:(id)sender {
    //run clickThread function in a separate thread
    [self performSelectorInBackground:@selector(clickThread) withObject:nil];
}

- (void) makeconnection:(NSString*)url {
    NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:url]];
    [NSURLConnection connectionWithRequest:request delegate:self];
}

- (void) clickThread {
    NSLog(@"making connection with google");
    //NSURLConnection will only work if it is run on the main thread
    [self performSelectorOnMainThread:@selector(makeconnection:) withObject:@"http://www.google.com" waitUntilDone:NO];
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    NSLog(@"google done");
    NSLog(@"%@", [[NSString alloc] initWithData:alldata encoding:NSUTF8StringEncoding]);
    
    NSLog(@"making connection with yahoo");
    sem = dispatch_semaphore_create(0);
    alldata = [[NSMutableData alloc] init];
    [self performSelectorOnMainThread:@selector(makeconnection:) withObject:@"http://www.yahoo.com" waitUntilDone:NO];
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    NSLog(@"yahoo done");
    NSLog(@"%@", [[NSString alloc] initWithData:alldata encoding:NSUTF8StringEncoding]);
}
@end

C# Multithreaded and Parallel Programming – Book Review

If you are a C# developer who is serious about developing high performance multithreaded applications, then this is the book for you. This book goes in-depth on how to develop multithreaded applications that will take advantage of today’s multicore processors.

Chapter 1 – Explains the history of processors in-depth from single core to multicore. The book also explains, with images, how the (Windows) operating system manages threads on a multicore system.

Chapter 2 – Discusses how to create a simple WPF (Windows Presentation Foundation) application using BackgroundWorker class to demonstrate a non-blocking application.

Chapter 3 & 4 – Discusses Thread class from beginner to advanced such as how to share data between threads to locking, deadlocks, and error handling.

Chapter 5, 6 & 7 – Introduction to Task Parallel Library (TPL). These chapters discusses how to use Parallel class and when to use it instead of the Thread class. The main take away from these chapters (and TPL) is to let .NET handle the thread coordination while the developer focus on the logic of the application.

Chapter 8 – How to take advantage of the tools in Visual Studio to help the developer debug multithreaded application.

Chapter 9 – Introduction to pipeline and producer-consumer design pattern. Discusses how to coordinate efficiently between threads where order matters. For example, thread A reads a frame of video file into a buffer, thread B immediately processes the frame, and thread C writes the frame to file. This process continues until all of the frame has been read from the video file.

Chapter 10 – Introduction of PLINQ. Discusses when and how to use PLINQ to process a LINQ query in parallel.

Chapter 11 – Introduction of async programming. Discusses the newest technique to create non-blocking applications such using async and await.

Overall, great book with examples and images to help the reader understand and apply multithreading features in .NET framework to their application. I highly recommend this book to anyone that wants in-depth practical understanding of multithreaded application in C#.

To findout more about this book, visit the Packt website:
https://www.packtpub.com/application-development/c-multithreaded-and-parallel-programming

Simple multithreaded server/client in Java

Server.java

import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
	public void Start()
	{
		try {
			ServerSocket serverSocket = new ServerSocket(5000);
			ExecutorService service = Executors.newFixedThreadPool(20);
			while(true)
			{
				final Socket socket = serverSocket.accept();
				
				service.submit(new Runnable() {
					
					@Override
					public void run() {
						try {
							StringBuilder sb = new StringBuilder();
							InputStreamReader br = new InputStreamReader(socket.getInputStream());
							int c;
							while((c = br.read()) != 0)
							{
								sb.append((char)c);
							}
							System.out.println("rec: " + sb.toString());
							
							DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS");
							Date date = new Date();
							DataOutputStream os = new DataOutputStream(socket.getOutputStream());
							String outStr = dateFormat.format(date) + '\0';
							
							os.write(outStr.getBytes());
							socket.close();
							System.out.println("sent: " + sb.toString());
						} catch (Exception e) {
							e.printStackTrace();
						}
						
					}
				});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		Server s = new Server();
		s.Start();
	}
}

Client.java

import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Client {
	public void Start()
	{
		final int NUMBER_OF_THREADS = 2000;
		ExecutorService service = Executors.newFixedThreadPool(20);
		
		for(int i = 0; i < NUMBER_OF_THREADS; i++)
		{
			service.submit(new Runnable() {
				
				@Override
				public void run() {
					try {
						StringBuilder sb = new StringBuilder();
						Socket s = new Socket("127.0.0.1", 5000);
						DataOutputStream os = new DataOutputStream(s.getOutputStream());
						Date date = new Date();
						DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS");
						String outStr = dateFormat.format(date) + '\0';
						os.write(outStr.getBytes());
						System.out.println("sent: " + outStr);
						
						InputStreamReader br = new InputStreamReader(s.getInputStream());
						int c;
						while((c = br.read()) != 0)
						{
							sb.append((char)c);
						}
						System.out.println("rec: " + sb.toString());
						s.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
					
				}
			});
		}
	}
	public static void main(String[] args) {
		Client c = new Client();
		c.Start();
		
		try {
			Thread.sleep(10000000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Simple multithreaded server/client in C#

Server Code

using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace server
{
    public class server
    {
        ManualResetEvent tcpClientConnected = new ManualResetEvent(false);

        void ProcessIncomingData(object obj)
        {
            TcpClient client = (TcpClient)obj;
            StringBuilder sb = new StringBuilder();

            using (NetworkStream stream = client.GetStream())
            {
                int i;
                while ((i = stream.ReadByte()) != 0)
                {
                    sb.Append((char)i);
                }

                string reply = "ack: " + sb.ToString() + '\0';
                stream.Write(Encoding.ASCII.GetBytes(reply), 0, reply.Length);
            }
            Console.WriteLine(sb.ToString());
        }

        void ProcessIncomingConnection(IAsyncResult ar)
        {
            TcpListener listener = (TcpListener)ar.AsyncState;
            TcpClient client = listener.EndAcceptTcpClient(ar);

            ThreadPool.QueueUserWorkItem(ProcessIncomingData, client);
            tcpClientConnected.Set();
        }

        public void start()
        {
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
            TcpListener listener = new TcpListener(endpoint);
            listener.Start();
            
            while (true)
            {
                tcpClientConnected.Reset();
                listener.BeginAcceptTcpClient(new AsyncCallback(ProcessIncomingConnection), listener);
                tcpClientConnected.WaitOne();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            server s = new server();
            s.start();
        }
    }
}

Client Code

using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace client
{
    class Program
    {
        const int NUMBER_OF_THREADS = 2000;
        void Work(object obj)
        {
            IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
            TcpClient client = new TcpClient();
            client.Connect(ep);

            StringBuilder sb = new StringBuilder();
            using (NetworkStream stream = client.GetStream())
            {
                string request = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt") + '\0';
                Console.WriteLine("sent: " + request);
                stream.Write(Encoding.ASCII.GetBytes(request), 0, request.Length);

                int i;
                while ((i = stream.ReadByte()) != 0)
                {
                    sb.Append((char)i);
                }
            }
            client.Close();

            Console.WriteLine(sb.ToString());
        }

        void start()
        {
            for (int i = 0; i < NUMBER_OF_THREADS; i++)
            {
                ThreadPool.QueueUserWorkItem(Work);
            }
        }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.start();

            //press any key to exit
            Console.ReadKey();
            Environment.Exit(0);
        }
    }
}

Using AsParallel for parallel processing

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            BigInteger[] factorialArray = new BigInteger[100000];
            for (int i = 0; i < 100000; i++)
                factorialArray[i] = i + 1;
            var y = factorialArray.AsParallel().Aggregate((factorial, i) => factorial * i);


            //632382 ^ 518061
            //make sure to run on a quad-core computer or else it will take very long
            BigInteger[] exponent = new BigInteger[518061];
            for (int i = 0; i < 518061; i++)
                exponent[i] = 632382;
            var g = exponent.AsParallel().Aggregate((product, i) => product * i);
        }
    }
}

ConcurrentDictionary in C#

class Program
{
    const int MAGIC_NUMBER = 250000;
    ConcurrentDictionary<Int32, Int32> c = new ConcurrentDictionary<Int32, Int32>();

    public Program()
    {
        Thread[] threads = new Thread[6];
        int i = 0;
        for (; i < 4; i++)
        {
            int temp = i + 1;
            threads[i] = new Thread(() => searchFunction(temp));
        }
        threads[i++] = new Thread(() =>
            {
                Random r = new Random();
                while (true)
                {
                    try
                    {
                        for (int j = 0; j < 10000; j++)
                        {
                            int num = r.Next();
                            c.TryAdd(num, num);
                        }
                        Thread.Sleep(10);
                    }
                    catch (ThreadInterruptedException)
                    {
                        return;
                    }
                }
            });
        threads[i++] = new Thread(() =>
        {
            Random r = new Random();
            while (true)
            {
                try
                {
                    c.TryAdd(MAGIC_NUMBER, MAGIC_NUMBER);
                    Console.WriteLine("-->Thread 6: Magic Number Inserted");
                    Thread.Sleep(5000);
                }
                catch (ThreadInterruptedException)
                {
                    return;
                }
            }
        });

        for (int j = 0; j < threads.Length; j++)
            threads[j].Start();

            Thread.Sleep(100000);


        for (int j = 0; j < threads.Length; j++)
            threads[j].Interrupt();
    }

    void searchFunction(int i)
    {
        int count = i;
        while (true)
        {
            try
            {
                Int32 outNum;
                bool b = c.TryRemove(MAGIC_NUMBER, out outNum);
                if (b == true)
                {
                    c.Clear();
                    Console.WriteLine("Thread " + count + ": Magic Number found. Object id: " + RuntimeHelpers.GetHashCode(outNum));
                }

                Thread.Sleep(10);
            }
            catch (ThreadInterruptedException)
            {
                return;
            }
        }
    }

    static void Main(string[] args)
    {
        new Program();
    }
}

ConcurrentHashMap in Java

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

public class Concurrenthashmap {
	static final int MAGIC_NUMBER = 250000;
	ConcurrentHashMap<Integer, Integer> c = new ConcurrentHashMap<Integer, Integer>();
	class searchClass implements Runnable
	{
		int id;
		public searchClass(int id) {
			this.id = id;
		}
		
		@Override
		public void run() {
			Integer i = new Integer(MAGIC_NUMBER);
			while(true)
			{
				try {
					Integer o = c.remove(i);
					if(o != null)
					{
						c.clear();
						System.out.println("Thread " + id + ": Magic Number found. Object id: " + System.identityHashCode(o));
					}
					
					Thread.sleep(10);
				} catch (InterruptedException e) {
					return;
				}
			}
		}
	}
	
	public Concurrenthashmap() {
		Thread [] threads = new Thread[6];
		int i = 0;
		for(; i < 4; i++)
			threads[i] = new Thread(new searchClass(i + 1));
		threads[i++] = new Thread(new Runnable() {
			@Override
			public void run() {
				Random r = new Random();
				while(true)
				{
					try {
						for(int i = 0; i < 10000; i++)
						{
							int num = r.nextInt();
							c.put(num, num);
						}
						Thread.sleep(10);
					} catch (InterruptedException e) {
						return;
					}
				}
			}
		});
		threads[i++] = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true)
				{
					try {
						c.put(MAGIC_NUMBER, MAGIC_NUMBER);
						System.out.println("-->Thread 6: Magic Number Inserted");
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						return;
					}
				}
			}
		});
		
		for(int j = 0; j < threads.length; j++)
			threads[j].start();
		
		try {
			Thread.sleep(100000);
		} catch (InterruptedException e) {
		}
		
		for(int j = 0; j < threads.length; j++)
			threads[j].interrupt();
	}

	public static void main(String[] args) {
		new Concurrenthashmap();
	}
}

Barrier in C#

class Program
{
    Barrier b = new Barrier(3);

    public Program()
    {
        Thread[] threads = new Thread[4];
        for (int i = 0; i < 4; i++)
        {
            threads[i] = new Thread(doSomething);
            threads[i].Start(i + 1);
        }

        Thread.Sleep(30000);

        for (int i = 0; i < 6; i++)
        {
            threads[i].Interrupt();
        }
    }

    void doSomething(object id)
    {
        int length = ((int)id) * 2;
        while (true)
        {
            try
            {
                Console.WriteLine("Thread " + id + ": Doing something for " + length + " seconds.");
                Thread.Sleep(length * 1000);
                Console.WriteLine("Thread " + id + ": Waiting");
                b.SignalAndWait();
            }
            catch (ThreadInterruptedException)
            {
                return;
            }
        }
    }

    static void Main(string[] args)
    {
        new Program();
    }
}

SemaphoreSlim in C#

class Program
{
    SemaphoreSlim sem = new SemaphoreSlim(2);

    public Program()
    {
        Thread []threads = new Thread[6];

        for (int i = 0; i < 6; i++)
        {
            int t = i + 1;
            threads[i] = new Thread(() => doSomething(t * 2, "Thread " + t));
            threads[i].Start();
        }
    }

    void doSomething(int length, string str)
    {
        sem.Wait();
        Console.WriteLine(str + ": Doing something for " + length + " seconds.");
        Thread.Sleep(length * 1000);
        sem.Release();
        Console.WriteLine(str + ": Done");
    }

    static void Main(string[] args)
    {
        new Program();
    }
}

CountdownEvent in C#

class Program
{
    CountdownEvent countdown = new CountdownEvent(3);

    public Program()
    {
        Thread t1 = new Thread(() => doSomething(4, "Thread 1"));
        Thread t2 = new Thread(() => doSomething(3, "Thread 2"));
        Thread t3 = new Thread(() => doSomething(2, "Thread 3"));

        t1.Start();
        t2.Start();
        t3.Start();

        t1.Join();
        t2.Join();
        t3.Join();
    }

    void doSomething(int length, string str)
    {
        Console.WriteLine(str + ": Doing Something for " + length);
        Thread.Sleep(length * 1000);
        Console.WriteLine(str + ": Done");
        countdown.Signal();
        Console.WriteLine(str + ": Waiting now");
        countdown.Wait();

        Console.WriteLine(str + ": Doing something else now for 3 seconds");
        Thread.Sleep(3000);
        Console.WriteLine(str + ": Done");
    }

    static void Main(string[] args)
    {
        new Program();
    }
}