using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Threading; public class Range { public long m_start; public long m_end; public long m_candidate; } [ServiceContractAttribute(ConfigurationName = "mapReplaceContract")] public interface IRangeInterface { [OperationContractAttribute] long? findDivisor(Range range); } class Program { static long m_primeCandidate = 2147483647; //Mersenne prime, in binary = 1111111111111111111111111111111 static int m_rangeForSingleThread = 12301; static long m_foundDivisors = 0; static long m_low = 2; static long m_high = m_low + m_rangeForSingleThread; static bool m_isLast = false; static Object m_obj = new Object(); static Range getNextRange() { lock (m_obj) { if (m_isLast) return null; Range range = new Range(); range.m_start = m_low; range.m_end = m_high; range.m_candidate = m_primeCandidate; m_low = m_high + 1; m_high = m_low + m_rangeForSingleThread; if (m_high >= m_primeCandidate) { m_high = m_primeCandidate - 1; m_isLast = true; } return range; } } static void startUpFunction(Object param) { string port = (string)param; string URI = "net.tcp://localhost:" + port.Trim() + "/AnyLocallyUniqueName"; ChannelFactory factory = new ChannelFactory(new NetTcpBinding(), new EndpointAddress(URI)); IRangeInterface channel = factory.CreateChannel(); long counter = 0; while (true) { Range range = getNextRange(); if (range == null) break; if (++counter % 500 == 0) { Console.Write("covered range {0} \r", range.m_end); } long? res = channel.findDivisor(range); if (res != null) { Console.WriteLine("Found divisor: {0}", res); Interlocked.Increment(ref m_foundDivisors); break; } } } static void Main() { Thread myThread1 = new Thread(new ParameterizedThreadStart(startUpFunction)); Thread myThread2 = new Thread(new ParameterizedThreadStart(startUpFunction)); Thread myThread3 = new Thread(new ParameterizedThreadStart(startUpFunction)); Thread myThread4 = new Thread(new ParameterizedThreadStart(startUpFunction)); //In order to start several threads on several different ports, the //according number of server instances should be started on same ports. myThread1.Start("101"); myThread2.Start("102"); myThread3.Start("103"); myThread4.Start("104"); //Attension: //Anyone can try to use different threads to access same server. It can be done //by using same URI (port number) in all threads. It may work without guaranteed result. //That means any particular call to channel.findDivisor(range) may //fail because server is still processing request of another thread. //I would advice to use an individual thread for each instance of server. myThread1.Join(); myThread2.Join(); myThread3.Join(); myThread4.Join(); Console.WriteLine(); if (m_foundDivisors <= 0) { Console.WriteLine("Divisors not found, candidate {0} is a prime.", m_primeCandidate); } } }