Showing posts with label MultiThread. Show all posts
Showing posts with label MultiThread. Show all posts

Wednesday, December 13, 2017

Different between Multi Thread and Asynchronous

  • Synchronous: you cook the eggs, then you cook the toast.
  • Asynchronous, single threaded: you start the eggs cooking and set a timer. You start the toast cooking, and set a timer. While they are both cooking, you clean the kitchen. When the timers go off you take the eggs off the heat and the toast out of the toaster and serve them.
  • Asynchronous, multithreaded: you hire two more cooks, one to cook eggs and one to cook toast. Now you have the problem of coordinating the cooks so that they do not conflict with each other in the kitchen when sharing resources. And you have to pay them.
  • Threading is about workers; Asynchronous is about tasks
  • Tasks where some tasks depend on the results of others; as each task completes it invokes the code that schedules the next task that can run, given the results of the just-completed task. But you only need one worker to perform all the tasks, not one worker per task.

async and await

  • async to create asynchronous method.
  • await is wait until the process is complete
  • If windows form has Async, it will show "loading" label and you can move form. 
  • Without Async, the form will hang and unhang when the task is finish.
Task
public async void btnProcess_click()
{
    Task<int> task = new Task<int>(CountChacaracter); //Function
    task.Start();

    lblCount.text = "Loading. Please wait";
    int count = await task; //wait for result
    lblCount.text = count.ToString();
}

Thread
UI thread (main thread) is invoke a new thread, you need to thread join to join back the thread. But It will Block the UI cannot move to wait the result.

public async void btnProcess_click()
{
    int count = 0;
    Thread thread = new Thread(() => { count = CountChacaracter(); });
    thread.Start();

    lblCount.text = "Loading. Please wait";
    thread.Join();
    lblCount.text = count.ToString();

}

With this, you can move the UI, but is not correct way, because only UI thread can modify the control, (it may or may not work, depend on luck)

Thread thread = new Thread(() => 
    count = CountChacaracter(); 
    lblcountText = count.tostring(); 
});

This is correct way, and same result as Task. But code is complicated, so use TASK!!

public async void btnProcess_click()
{
    int count = 0;
    Thread thread = new Thread(() =>
    {
        count = CountChacaracter();
        Action action = new Action(SetLabel(count));
        this.BeginInvoke(action);
    });

    thread.Start(); 
    lblCount.text = "Loading. Please wait";
}

private void SetLabel(int count)
{
    lblCount.text = count.ToString();
}

Tuesday, August 16, 2016

AutoResetEvent vs ManualResetEvent

This 2 is a signaling methodology. E.g. you have 2 thread , Thread 2 can call Thread 1 stop in middle, and call thread 1 continue run again later.

AutoResetEvent
Only allow 1 Thread to run, if u have 3 WaitOne(), you need to have 3 Set().

ManualResetEvent
Allow all Thread to run, if u have 3 WaitOne(), you only need to have 1 Set().


// static AutoResetEvent objAuto = new AutoResetEvent(false);
static ManualResetEvent objAuto = new ManualResetEvent(false);

static void Main(string[] args)
{
    new Thread(SomeMethod).Start();
    Console.WriteLine("Main");
    Console.ReadLine();
    objAuto.Set();
    Console.ReadLine();
    objAuto.Set();
    Console.ReadLine();
}

static void SomeMethod()
{
    Console.WriteLine("Start 1");
    objAuto.WaitOne();
    Console.WriteLine("Finish 1");
    Console.WriteLine("Start 2");
    objAuto.WaitOne();
    Console.WriteLine("Finish 2");
}



Result (Auto)

------
Main
Start 1
(Enter)
Finish 1
Start 2
(Enter)
Finish 2

Result (Manual)
------
Main
Start 1
(Enter)
Finish 1
Start 2
Finish 2


Tuesday, August 9, 2016

Volatile

2 Threads sync the variable, e.g. Thread 1 set true, the true value will bring to Thread 2.
if without volatile , the step 3 will not run, and stop in while loop. (Run in Release Mode)

 private volatile bool _loop = true;

 static void Main(string[] args)
 {
     Program test1 = new Program();
     Thread obj = new Thread(SomeThread);
     obj.Start(test1);

     Thread.Sleep(200);
     test1._loop = false;
     Console.WriteLine("Step 2 : Value is set to False");
 }

 private static void SomeThread(object o1)
 {
     Program o = (Program)o1;
     Console.WriteLine("Step 1 - Enter Loop");
     while (o._loop)
     {
     }
     Console.WriteLine("Step 3 - Exit Loop");
 }

Threat Safe

Threads are lightweight processes
Normally programs where a single thread runs as a single process which is the running instance of the application. 


1)Semaphore Class

  • Limits the number of threads that can access a resource or pool of resources concurrently.
  • Semaphore is advance version of mutex with additional features. 
  • Work with Internal or External threads
  • Threads enter the semaphore by calling the WaitOne method, and release the semaphore by calling the Release method.
  • The count on a semaphore is decrease each time a thread enters the semaphore, and incremented when a thread releases the semaphore. When the count is zero, subsequent requests block until other threads release the semaphore.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.
  • A thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. 
  • To release some or all of these entries, the thread can call the parameterless Release() method overload multiple times, or it can call the Release(Int32) method overload that specifies the number of entries to be released, Relase() same as Release(1)
  • SemaphoreFullException is thrown when full.
  • All will stop at WaitOne(), waitOne() bellow code will not be run when the semaphore is full , it run when someone call Release().
  • There is no guaranteed order, such as FIFO or LIFO.
2)Lock/Monitor
  • Only 1 thread enter. If another thread tries to enter a locked code, it will wait, block, until the object is released. (internal thread - within application itself)
  • Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.
  • You can't use the await keyword in the body of a lock statement.(private Object thisLock = new Object();)
3)Mutex
Mutex ensures the thread safety which are out process that is threads (Only One Thread) which
coming from outside of an application (External threads). 

4)SemaphoreSlim

SemaphoreSlim is an advance version of Monitor. SemaphoreSlim ensures the thread safety with internal threads but between scope of SemaphoreSlim it allows us to pass one or more threads to pass and executes their task. SemaphoreSlim also provides you an advance limit where you can limit the number of threads for an execution.

Lock vs SemaphoreSlim

Both is internal threads, Lock only 1 entry and semaphoreSlim can limit numbers of entry
Different Lock and Mutex
lock is specific to the AppDomain, while Mutex to the Operating System allowing you to perform cross-process locking and synchronization.


Different Mutex and Semaphore 
Both is external threads, Mutex only 1 entry and Semaphore can limit numbers of entry.


Only One
More Than One
Internal Thread
Lock/Monitor
SemaphoreSlim
External Thread
Mutex
Semaphore

Saturday, December 26, 2015

Task VS Thread

Threads run in a shared memory space


Processes run in separate memory spaces. each process has its own memory space and at least 1 thread, know as primary thread.

Thread
  1. Able observe its state. (specify name for debugging, Show in UI)
  2. Able to set thread-level properties (stack size, apartment state, or culture)
  3. Maintain an object owned by a single thread. ( Only used by that thread)
  4. Problem : costly, Each thread consumes a non-trivial amount of memory for its stack

ThreadPool
  1. Is a wrapper around a pool of threads, no create its own OS thread.
  2. Use for Short Operations & no result return.
  3. Use to avoid overhead of creating too many threads. 
  4. Able to execute at some point.
  5. Able control the size of the pool, 
  6. Not able to tell the pool start running the work.
  7. It will full , if too many long-running tasks.
  8. Not able to get the result (which item has been completed.)
Task
  1. Is lightweight object for managing a parallelizable unit of work. (work something in Parallel).Parallel means the work is spread across multiple processors to maximize computational speed.
  2. Does not create its own OS thread.(Executed by a TaskScheduler, run on threadPool)
  3. Unlike the ThreadPool, Task able to find out when it finishes, to return a result.
  4. Call ContinueWith() to run more code once the task finishes, and pass you the task's result.
  5. Call Wait() to synchronously wait for a task to finish. Like Thread.Join(), this will block the calling thread until the task finishes. Synchronously waiting for a task is bad idea; it prevents the calling thread from doing any other work, and lead to deadlocks if the task ends up waiting (even asynchronously) for the current thread.
  6.  Parallel.For*() methods, PLINQ, C# 5 await, and modern async methods in the BCL, are all built on Task.
Conclusion
Task is almost always the best option; it provides a much more powerful API and avoids wasting OS threads.

Sunday, December 20, 2015

Task vs parallel

Parallel is faster than Task.

Task
task = new Task(() => DoSomething());
task.Start();
task.Wait();

------------------

Action action = new Action(() => SendSMSAsync(DoSomething()));

Parallel.Invoke(action);