Threadpool + Polling C# .Net 3.5 - c#

Hi I am new to multithreading and would like to ask for your advice and guidance.
We have a service running on our server to poll data for notifications on our clients. We wanted the service to process data faster. Currently, our existing service polls and processes data on a single thread which sometimes causes delay to the notifications on hourly bases. My plan is to use ThreadPool to process data concurrently. I have this piece of code that simulates my plan and idea.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Security;
using System.Text;
using System.Threading;
using System.Xml;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Web;
namespace ThreadPooling
{
class Program
{
static int nMaxRecord = 0;
static ManualResetEvent mre = new ManualResetEvent(false);
static Timer TestThread = null;
static void Main(string[] args)
{
TestThread = new Timer(new TimerCallback(ProcessWithThreadPoolMethod), null, 500, Timeout.Infinite);
Thread.Sleep(Timeout.Infinite);
}
static void ProcessWithThreadPoolMethod(object ostate) // Sample processing of data
{
nMaxRecord = 1300;
ThreadPool.SetMaxThreads(3, 0);
for (int i = 0; i < 1300; i++)
{
ThreadPool.QueueUserWorkItem(ProcessWithThreadMethod, i);
}
mre.WaitOne();
Console.WriteLine("Test");
TestThread.Change(5000, Timeout.Infinite);
}
static void ProcessWithThreadMethod(object callback)
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine((int)callback);
}
if(Interlocked.Decrement(ref nMaxRecord) == 0)
{
mre.Set();
}
}
}
}
While running the console application, I noticed that the thread count keeps increasing although I limited the maxthreads in the ThreadPool by 3. Am I doing the right thing? Would like to ask some guidance and Pros and Cons on my concept.

You should test the return value of:
ThreadPool.SetMaxThreads(3, 0); //returns false on normal machines.
It's unable to process the change due to this:
You cannot set the maximum number of worker threads or I/O completion threads to a number smaller than the number of processors on the computer. To determine how many processors are present, retrieve the value of the Environment.ProcessorCount property. In addition, you cannot set the maximum number of worker threads or I/O completion threads to a number smaller than the corresponding minimum number of worker threads or I/O completion threads. To determine the minimum thread pool size, call the GetMinThreads method.
See: MSDN
So, what you can do is something like this;
ThreadPool.SetMaxThreads(16, 16);
But I assume you were trying to down-throttle the ThreadPool. In general that's not a good idea. You'll need an alternative for such logic.
A semaphore might be an option, as described here, or the pattern #Fildor describes.

You cannot throttle the threadpool, but why not just have a simple increment/decrement counter that you check before launching a new thread ?
In pseudo code-
volatile int currentThreadCount = 0;
void myWorkLauncher()
{
while(<I have work to do>)
{
if(currentThreadCount < threshold)
{
currentThreadCount ++;
ThreadPool.QueueUserWorkItem(workerFunc);
}
else
{
Thread.Sleep(500);
}
}
Thread.Sleep(500);
}
The last line of the workedFunc just decrements the value.
You can do all sorts of fancy stuff like wrapping your workerFunc in an Action() which itself decrements the counter, preventing your workerFunc from needing any connection to the myWorkLauncher class. Alternatively you can replace the simplistic Thread.Sleep with a AutoResetEvent or similar.

Related

Doesn't ThreadPriority.Highest guarantee finishing before ThreadPriority.Lowest?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication58
{
class MultiThreading
{
static void Main(string[] args)
{
MultiThreading mul = new MultiThreading();
Thread t1 = new Thread(new ThreadStart(mul.WriteX));
Thread t2 = new Thread(new ThreadStart(mul.WriteO));
t1.Priority = ThreadPriority.Lowest;
t2.Priority = ThreadPriority.Highest;
t1.Start();
t2.Start();
}
private void WriteX()
{
for (int i = 0; i < 300; i++)
{
Console.Write("X");
}
}
private void WriteO()
{
for (int i = 0; i < 300; i++)
{
Console.Write("O");
}
}
}
}
When I execute above code, I expect X's end of the printing job because I gave that method lowest priority but sometimes I get O's at the end. I mean doesn't giving high priority to 2nd thread guarantee it will finish sooner?
There is no practical guarantee about thread scheduling induced by the priority setting.
For example, the high priority thread could block on IO or a page fault. Then, another thread can execute.
This is not a good way to synchronize threads.
Three hundreds operations for CPU is part of second. I recommend you to think about your problem and applications as a statistical experiment.
Repeat your experiment many times, because running few of them is not trustworthy. It happens because population (number of iterations it is not big enough). I tried to run this application few times, but with 3 000 000 iterations and I let to write for 45 seconds (while(true) and Thread.Sleep(45000)). Task with higher priority finished first.
Your OS, CPU and PC configuration does matter.

C# (.net 3.5) run thread together

How can I sync threads to run together.
For example:
code
Code section A
code
I want that every 5 thread will enter together to the Section A
Here's some sample code which shows how to use the Barrier class to wait for 5 threads to all be at the same point in the code before being allowed to carry on.
To try it out, run it and then ^C to stop it after a while, and inspect the times when the threads pass the barrier. You'll see that it is waiting until 5 threads are all at the barrier, then they are all released at once (whereupon the Barrier waits for the next 5 threads to be ready).
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Barrier barrier = new Barrier(5); // 5 == #participating threads.
Action[] actions = new Action[10];
var sw = Stopwatch.StartNew();
ThreadPool.SetMinThreads(12, 12); // Prevent delay on starting threads.
// Not recommended for non-test code!
for (int i = 0; i < actions.Length; ++i)
actions[i] = () => test(barrier, sw);
Parallel.Invoke(actions);
}
static void test(Barrier barrier, Stopwatch sw)
{
int id = Thread.CurrentThread.ManagedThreadId;
Random rng = new Random(id);
while (true)
{
int wait = 5000 + rng.Next(5000);
Console.WriteLine($"[{sw.ElapsedMilliseconds:000000}] Thread {id} is sleeping for {wait} ms.");
Thread.Sleep(wait);
Console.WriteLine($"[{sw.ElapsedMilliseconds:000000}] Thread {id} is waiting at the barrier.");
barrier.SignalAndWait();
Console.WriteLine($"[{sw.ElapsedMilliseconds:000000}] Thread {id} passed the barrier.");
Thread.Sleep(1000); // This is the equivalent of your "Section A".
}
}
}
}

Is there a better way to count passed time without putting thread to sleep

I am looking at the code written by my colleague:
long tim = DateTime.Now.Ticks;// get current time in ticks
long startWait = tim + TimeSpan.TicksPerSecond * 15; // add 15 seconds (in ticks) to current time
while ((tim < startWait) & !_myReader.ReaderOpen) //_myReader.ReaderOpen is external device
{
Thread.Sleep(100); // sleep for 100ms
tim = DateTime.Now.Ticks;
}
For some reason, this code does not look right. It seems like putting thread to sleep and waking it up every 100ms is huge waste of CPU.
You can use a Timer to execute periodically without forcing a thread to be sitting around doing nothing for the duration of that time. it's also possible that the reader that you're using exposes some means of notifying you when things happen so that you can respond to those events without needing to poll the object.
you could also do something like this which is exactly the same thing but different
at least you can stop the loop when myReader.ReaderOpen become true, if the 100ms is important to you
using System;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
const int TimeToWait = 15;
var sw = Stopwatch.StartNew();
var mnu = new ManualResetEvent(false);
while (sw.Elapsed.Seconds <= TimeToWait)
{
Console.WriteLine(sw.ElapsedMilliseconds);
mnu.WaitOne(100);
}
Console.ReadKey();
}
}
}

How can I measure the time of a thread in c#? [duplicate]

This question already has answers here:
How can I get CPU usage and/or RAM usage of a *THREAD* in C# (managed code)?
(4 answers)
Closed 9 years ago.
I want to measure the time that a C# routine needs. Because there are many other threads I only want to count the time of this one thread. In Java I can use getCurrentThreadCpuTime.
How can I do it?
You should look into PerformanceCounters. They are quite complex and can be a bit of a pain to set up, but are robust in what they offer for metrics. A couple of things that might help:
Performance counters and threading
http://blogs.msdn.com/b/adamhems/archive/2008/12/04/using-custom-performance-counters-to-measure-multi-threaded-operation-durations.aspx
You can't. You cannot measure the accumulated time ON THE CPU for a particular thread.
The most accurate thing you could do would be to spin off a separate process for each of your tasks, and then measure the CPU time for the process (which actually can be done in .Net)... but that's overkill.
If you need help on how to do that, you should ask another question specifically for that.
You can use Stopwatch for that. It would be the simplest way to get that.
public void Worker()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
///Do your wwork here
var timeElapsed = stopwatch.Elapsed;
}
UPDATE
I got your question wrong, so what about this? It does not work if you use thread sleep. Sorry if this still is not what you're looking for.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;
namespace ConsoleApplication2
{
class Program
{
static ConcurrentDictionary<int, ProcessThread> threadIdsMapping = new ConcurrentDictionary<int, ProcessThread>();
static void Main(string[] args)
{
Thread oThread = new Thread(
delegate()
{
threadIdsMapping.GetOrAdd(Thread.CurrentThread.ManagedThreadId, GetProcessThreadFromWin32ThreadId(null));
long counter = 1;
while (counter < 1000000000)
{
counter++;
}
});
oThread.Start();
oThread.Join();
Console.WriteLine(threadIdsMapping[oThread.ManagedThreadId].TotalProcessorTime);
Console.WriteLine(threadIdsMapping[oThread.ManagedThreadId].UserProcessorTime);
Console.WriteLine(DateTime.Now - threadIdsMapping[oThread.ManagedThreadId].StartTime);
Console.ReadKey();
}
public static ProcessThread GetProcessThreadFromWin32ThreadId(int? threadId)
{
if (!threadId.HasValue)
{
threadId = GetCurrentWin32ThreadId();
}
foreach (Process process in Process.GetProcesses())
{
foreach (ProcessThread processThread in process.Threads)
{
if (processThread.Id == threadId) return processThread;
}
}
throw new Exception();
}
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();
}
}

How to queue a completion port action (I/O bound function) to CLR ThreadPool

I have an external library that does long running I/O. I wish to create a multithreaded application that will use ThreadPool to limit simultaneous number of threads and I wish to add threads handing these external calls as completion port thread (I/O threads) rather than worker threads (so that limit for compute bound threads) is intact.
I have a code sample, that omits external library but shows what I've tried already.
Does anyone know how to do that? Or is it even possible. Thank you
using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ThreadPoolTest
{
class MainApp
{
static void Main()
{
ThreadPool.SetMaxThreads(10, 10);
ThreadPool.QueueUserWorkItem(DoWork); //doesn't work - a compute-bound thread
ThreadPool.SetMaxThreads(10, 10);
//doesn't work - still a compute-bound thread
((Action<object>)DoWork).BeginInvoke(null, Callback, null);
Console.Read();
}
static void DoWork(object o)
{
ShowAvailableThreads();
//call to external library - that does a long I/O operation
Thread.Sleep(10);
}
static void Callback(IAsyncResult ar)
{
ShowAvailableThreads();
}
static void ShowAvailableThreads()
{
int workerThreads, completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads,
out completionPortThreads);
Console.WriteLine("WorkerThreads: {0}," +
" CompletionPortThreads: {1}",
workerThreads, completionPortThreads);
}
}
}
You can queue work for the I/O threads as described here.
The managed QueueUserWorkItem queues
work to the "worker threads" only.
UnsafeQueueNativeOverlapped queues to
the I/O threads, as do completions for
asynchronous I/O performed on kernel
objects that have been bound to the
ThreadPool via BindHandle.

Categories

Resources