I have windows project and one form which have timer for each 5 seconds.
It calls and processes methods from request named table time wise and condition wise.
But I have some methods types which takes too much time to respond and want those methods in separate thread. So that I can run those both request types in separate threads and syncs.
How can I do separate those both using thread -- multi async threads?
I recommend you look at the .NET 4.0 Task class. Firing full threads every time might be overkill. Tasks, together with timers use the underlying thread pool to execute work in parallel.
Using a Task is as simple as:
Task t = Task.Factory.StartNew(
() =>
{
// task code here
});
using System;
using System.Threading;
class Program
{
static void Main()
{
Thread thread1 = new Thread(new ThreadStart(A));
Thread thread2 = new Thread(new ThreadStart(B));
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
}
static void A()
{
Thread.Sleep(100);
Console.WriteLine('A');
}
static void B()
{
Thread.Sleep(1000);
Console.WriteLine('B');
}
}
Threading Tutorial
Related
I recently came across some code which confused me heavily, I have always thought that you must use threads or Async tasks, not mix and match between them,
public async Task DoWork()
{
Task.Delay(1000);
}
Now I saw code calling this like so:
public void Main()
{
var thread = new Thread(async () => { await DoWorkAync(); })
{
Priority = ThreadPriority.Highest,
IsBackground = true
};
// Start thread
proccessThread.Start();
}
Now this magically seemed to NOT create a thread each time it was run, it seemed to be using the ThreadPool.
now what I am struggling to understand is the difference between the above and:
public void Main()
{
var task = Task.Run(DoWorkASync);
}
From my testing, it seems that C# Thread has a different functionality when passing in an Async Expression vs the standard method on which to run>
This construct:
var thread = new Thread(async () => { await DoWorkAync(); });
// Start thread
proccessThread.Start();
Calls Thread constructor overload accepting ThreadStart delegate, and ThreadStart delegate is () => void. So you have this:
var thread = new Thread(StuffYourThreadExecutes);
thread.Start();
static async void StuffYourThreadExecutes() {
await DoWorkAsync();
}
So you start new thread and it runs the code until first asynchronous operation begins. Then thread exists. After that first asynchronous operation completes - the rest executes on whatever thread task scheduler providers (usually thread pool thread). Any exceptions which happen during this process cannot be observed.
For example if DoWorkAsync is something like:
static async Task DoWorkAsync(){
await Task.Delay(1000);
}
Then thread starts and almost immediately exits, doing nothing useful.
Task.Run, when passing async delegate there, does what is stated in docs:
Queues the specified work to run on the thread pool and returns a
proxy for the task
So whole operation just runs on thread pool thread without creating threads for nothing. You can observe exceptions by awaiting task returned by Task.Run.
I am learning TPL and stuck with a doubt. It is only for learning purpose and I hope people will guide me in the correct direction.
I want only one thread to access the variable sum at one time so that it does not get overwritten.
The code I have is below.
using System;
using System.Threading.Tasks;
class ThreadTest
{
private Object thisLock = new Object();
static int sum = 0;
public void RunMe()
{
lock (thisLock)
{
sum = sum + 1;
}
}
static void Main()
{
ThreadTest b = new ThreadTest();
Task t1 = new Task(()=>b.RunMe());
Task t2= new Task(() => b.RunMe());
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(sum.ToString());
Console.ReadLine();
}
}
Question -Am i right in this code ?
Question-Can I do it without lock because I read it somewhere that it should be avoided as it does not allow task to communicate with each other.I have seen some examples with async and await but I am using .Net 4.0 .
Thanks
Am i right in this code
Implementation wise Yes, but understanding wise No, as you have mixed up the new and old world while trying to implement the logic, let me try to explain in detail.
Task t1 = new Task(()=>b.RunMe()); doesn't mean as expected as in case of Thread API a new thread every time
Task API will invoke a thread pool thread, so chances are two Task objects t1,t2, gets executed on same thread most of the times for a short running logic and there's never a race condition, which needs an explicit lock, while trying to update the shared object
Better way to prevent race condition for Sum object would be Interlocked.Increment(ref sum), which is a thread safe mechanism to do basic operations on primitive types
For the kind of operation you are doing a better API would be Parallel.For, instead of creating a separate Task, the benefit would be you can run any number of such increment operations with minimal effort, instead of creating a Separate Task and it automatically blocks the Main thread, so your code shall look like:
using System;
using System.Threading.Tasks;
class ThreadTest
{
public static int sum;
}
static void Main()
{
Parallel.For(0, 1, i =>
{
// Some thread instrumentation
Console.WriteLine("i = {0}, thread = {1}", i,
Thread.CurrentThread.ManagedThreadId);
Interlocked.Increment(ref ThreadTest.sum);
});
Console.WriteLine(ThreadTest.sum.ToString());
Console.ReadLine();
}
}
While using the Thread instrumentation you will find that chances are that for two loops, 0,1, managed thread id is same, thus obviating the need for thread safety as suggested earlier
Answer 1:
This is threadsafe for the code that you posted.
However, as Sam has pointed out, this is not currently threadsafe in the general case because the field being incremented is static, but the locking object is not static.
This means that two separate instances of ThreadTest could be created on two separate threads, and then RunMe() could be called from those threads and because each instance has a separate locking object, the locking wouldn't work.
The solution here is to make the locking object static too.
Answer 2:
You can do this without explicit locking using Interlocked.Increment():
public void RunMe()
{
Interlocked.Increment(ref sum);
}
Now to the point, as I was adding some unhappy comments about downvotes, that have no reasons:).
Your scenario is working and is classic multithreading usage.
Classic because of using system lock, that is lock are actually WinAPI locks of the OS, so in order to synchronize, the code has to manage to ring down to the OS and back and of course lose some time with switching threads as some contention may happen especially if you would access RunMe multiple times in each thread running given task or created even more concurrent tasks thank 2.
Please try look on atomic operations.
For your scenario it would work very well, Interlocked.Increment(ref sum).
From there you have to restrain yourself from directly accessing the sum, but that is not a problem, because the Increment method is returning latest result.
Another option is to use SpinLock, that is IF YOU OPERATION IS REALLY FAST.
NEVER ON something ,like Console.WriteLine or any other system operations or long running calculations etc.
Here Inrelocked examples:
using System;
using System.Threading;
using System.Threading.Tasks;
class ThreadTest
{
/// <summary> DO NOT TOUCH ME DIRECTLY </summary>
private static int sum/* = 0 zero is default*/;
private static int Add(int add) => Interlocked.Add(ref sum, add);
private static int Increment() => Interlocked.Increment(ref sum);
private static int Latest() => Interlocked.Add(ref sum, 0);
private static void RunMe() => Increment();
static void Main()
{
Task t1 = new Task(RunMe);
Task t2 = new Task(RunMe);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine(Latest().ToString());
Console.ReadLine();
}
}
Is there a way to set a value for how long a thread should (maximally) be alive when you start the thread?
Said in another way, with "pseudocode", is there anything like this:
Thread t = new Thread();
t.start();
t.abort_after_x_seconds(30);
which would make the thread abort if it lived more than 30 seconds.
Edit: I still can't get it to work, what I originally had is:
while(true)
{
if(...)
{
Thread t = new Thread(new ThreadStart(startMethod));
t.start();
}
Thread.sleep(...);
}
the problem is that sometimes the threads will hang (I'm not implementing what the threads do so I don't know exactly why (it's a school project, we're noobs at organizing)), so I want to kill those threads. I tried using Tasks and CancellationTokens as in the examples below, but when the Task hangs
it can't check if a cancellation request has occured.
Most of the time, you shouldn't be using Threads, use Tasks instead. They are more convenient and more efficient.
Aborting something is not safe, you should use cooperative cancellation instead. If you're calling a method that supports cancellation, then just pass it a cancellation token that will be cancelled after 30 seconds.
So your code could look like this (using .Net 4.5):
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)));
var task = Task.Run(() => YourMethod(cts.Token), cts.Token);
[EDIT: My response was far too slow. But I'll leave this here for the sample code.]
You should use co-operative cancellation for this purpose. The thread itself will need to detect when it should exit, and respond appropriately.
There's a thing called a CancellationToken produced from a CancellationTokenSource that you can use for this purpose.
There's even a CancellationTokenSource constructor which lets you set a timeout.
Here's some sample code to demonstrate its use:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
private void run()
{
using (var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
{
var task = Task.Run(() => exampleOne(tokenSource.Token));
task.Wait();
}
using (var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
{
var task = Task.Run(() => exampleTwo(tokenSource.Token));
task.Wait();
}
Console.WriteLine("Done.");
}
static void exampleZero()
{
Console.WriteLine("Starting exampleZero()");
try
{
Thread.Sleep(10000); // Simulate work.
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation cancelled.");
}
Console.WriteLine("Exiting exampleZero()");
}
static void exampleOne(CancellationToken cancellation)
{
Console.WriteLine("Starting exampleOne()");
// Busy loop processing.
while (!cancellation.IsCancellationRequested)
{
// Do some work.
}
Console.WriteLine("Exiting exampleOne()");
}
static void exampleTwo(CancellationToken cancellation)
{
Console.WriteLine("Starting exampleTwo()");
while (!cancellation.WaitHandle.WaitOne(100)) // Wait 100ms between work.
{
// Do some work.
}
Console.WriteLine("Exiting exampleTwo()");
}
static void Main()
{
new Program().run();
}
}
}
As commenters have said, using Abort is bad practice and not guaranteed to abort immediately.
Why would you want to keep the thread alive? The thread will be released back to the pool when the task assigned to it is completed. The next time the task is run on the thread will automatically be given from the pool of threads either by creating another new one or re-using one that is available in the threadpool.
Sounds like your logic/code is bad and needs to be fixed rather than waiting for something for x seconds then terminating it, which in itself will cause knock on problems.
Perhaps you need a timer instead which can tick after 30 seconds then you can disable the timer and kill the task at hand.
How would I go about in creating a thread in C#?
In java I would either implement the Runnable interface
class MyThread implements Runnable{
public void run(){
//metthod
}
and then
MyThread mt = new MyThread;
Thread tt = new Thread(mt);
tt.start()
or I could simply extend the Thread class
class MyThread extends Thread{
public void run(){
//method body
}
and then
MyThread mt = new MyThread
mt.start();
No, contrary to Java, in .NET you can't extend the Thread class because it's sealed.
So to execute a function in a new thread the most naive way is to manually spawn a new thread and pass it the function to be executed (as anonymous function in this case):
Thread thread = new Thread(() =>
{
// put the code here that you want to be executed in a new thread
});
thread.Start();
or if you don't want to use an anonymous delegate then define a method:
public void SomeMethod()
{
// put the code here that you want to be executed in a new thread
}
and then within the same class start a new thread passing the reference to this method:
Thread thread = new Thread(SomeMethod);
thread.Start();
and if you want to pass parameters to the method:
public void SomeMethod(object someParameter)
{
// put the code here that you want to be executed in a new thread
}
and then:
Thread thread = new Thread(SomeMethod);
thread.Start("this is some value");
That's the native way to execute tasks in background threads. To avoid paying the high price of creating new threads you could use one of the threads from the ThreadPool:
ThreadPool.QueueUserWorkItem(() =>
{
// put the code here that you want to be executed in a new thread
});
or using an asynchronous delegate execution:
Action someMethod = () =>
{
// put the code here that you want to be executed in a new thread
};
someMethod.BeginInvoke(ar =>
{
((Action)ar.AsyncState).EndInvoke(ar);
}, someMethod);
And yet another, and more modern way to execute such tasks is to use the TPL (starting from .NET 4.0):
Task.Factory.StartNew(() =>
{
// put the code here that you want to be executed in a new thread
});
So, yeah, as you can see, there are like gazzilions of techniques that could be used to run a bunch of code on a separate thread.
I have a .NET 4.0 ASP.NET project which requires some threading work I've never really messed with before and I've been looking at this for days and I'm still clueless =/
Basically I want something like when you take a ticket at the deli and wait your turn before they get back to you. I'll try and relate this and see if it makes any sense...
function starts ---> gets to section where it needs to "take a ticket" (I assume queue some type of item in a blockingcollection) and waits until other "tickets" (a.k.a other instances of the same function) are completed before it gives the function the OK to resume (blocking collection gets to the item in the queue) ---> finish function.
I don't need/want to do any work in the queue, I just want the function to statically wait it's turn among other instances of the function. Does that make sense? Is that possible?
Please provide code if possible as I've seen tons of examples but none of them make sense/don't do what I want.
If you want to have the timer solution, I'd enqueue all operations into a BlockingCollection and have a dedicated thread dequeue them. This thread would wait 5s and then push the dequeued item onto the thread pool. This dedicated thread should do this in an infinite loop. Dequeue, wait, push.
What I actually recommend however, is that you use the SemaphoreSlim class to throttle the number of concurrent requests to this fragile web service. Probably you should pick a number between 1 and 5 or so as the allowed amount of concurrency.
Alright so after researching document after document and playing with numerous rewrites of code I finally figured out I wasn't using the AutoResetEvent right and how to use a blocking collection on a dedicated thread. So here was the final solution using an AutoResetEvent with a BlockingCollection. This solution below might not show the same results 100% of the time (just because I believe it has to do with thread timing of when something was entered into the blocking collection) but the end result is that it does exactly what I want.
class Program
{
static void Main(string[] args)
{
TaskProcessor tp = new TaskProcessor();
Thread t1 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest));
t1.Start(1);
Thread t2 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest));
t2.Start(2);
Thread t3 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest));
t3.Start(3);
}
}
class TaskProcessor
{
private AutoResetEvent _Ticket;
public TaskProcessor()
{
_Continue = new AutoResetEvent(false);
}
public void SubmitRequest(object i)
{
TicketingQueue dt = new TicketingQueue();
Console.WriteLine("Grab ticket for customer {0}", (int)i);
dt.GrabTicket(_Ticket);
_Continue.WaitOne();
Console.WriteLine("Customer {0}'s turn", (int)i);
}
}
public class TicketingQueue
{
private static BlockingCollection<AutoResetEvent> tickets = new BlockingCollection<AutoResetEvent>();
static TicketingQueue()
{
var thread = new Thread(
() =>
{
while (true)
{
AutoResetEvent e = tickets.Take();
e.Set();
Thread.Sleep(1000);
}
});
thread.Start();
}
public void GrabTicket(AutoResetEvent e)
{
tickets.Add(e);
}
}