Suppose I have a static method like so:
public static string ProcessMessage()
{
string testString = " this is test ";
....
return testString ;
}
and another method SendMessage:
public void SendMessage()
{
Thread th = new Thread(this.ProcessMessage);
th.Start();
th.Join();
}
What happens when SendMessage is called several times one right after another.
Suppose first thread calls ProcessMessage and is at line 1 and another thread calls ProcessMessage, what happens to the first thread? will it ever finish, since ProcessMessage is a static method? what will ProcessMessage properties look like? will thread 2 overwrite thread 1?
To answer your general question, multiple threads can call a static method, and each thread will process that method call separately. If static variables are used within the static method, then you may run into cross-threading issues, due to those variables being shared among multiple threads, but the method code itself is simply a set of instructions that will be followed by whatever threads enter it.
In regards to your specific example, the Thread Constructor can only be passed either a ParameterizedThreadStart or a ThreadStart object (and possibly an Int32). Both types of ThreadStart parameters are delegates with void signatures (they cannot return anything).
Also, since you are calling Thread.Start, followed by Thread.Join. Thread.Join blocks the calling thread until the waited on thread completes. Since that is the case, multiple calls to SendMessage() from the same thread will never spawn multiple simultaneous threads. Instead, each call will create a new thread and then wait for it to finish before moving on to the next call to SendMesage(). This is no better than simply calling ProcessMessage in the original thread.
Related
In a class I've two methods:
Method1(): void
Method2(): void
This class can be accessed by multiple threads.
How can I realise, if "thread1" call "Method1", that "thread2" is waiting in "Method2" or in "Method1". This logic should also work, if "thread2" is calling "Method2", that "thread1" is waiting in "Method1" or "Method2"
My idea is this:
private object _lock = new object();
void Method1() {
lock(_lock){
//TODO: do something
}
}
void Method2() {
lock(_lock){
//TODO: do something
}
}
Will this work?
Your code will work after your clarification in comments.
With the given code you will:
Ensure only one thread can execute either Method1 or Method2 at the same time
If one thread is inside Method1, other threads will wait if they try to call either Method1 or Method2.
If Method1 calls into Method2 or vice versa, this will also work as the same thread can lock the same object more than once.
In other words, this is not a deadlock:
lock (x)
lock (x)
....
So your code should work just fine.
You cant do on same object, You can use Monitor. Monitor allows re-entrancy
You can use the WaitOne() function of an AutoResetEvent to allow only one function to access resources at a time, when it's finished called Set().
Example here: Synchronizing two threads with AutoResetEvent
MSDN Reference: https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx
Your methods should be Synchronized. See C# version of java's synchronized keyword? to get an idea on how to do it in c#.
This will work. Since you're locking on the same object, only one lock { } block will be executed at a given time.
How can I realise, if "thread1" call "Method1", that "thread2" is waiting in "Method2" or in "Method1". This logic should also work, if "thread2" is calling "Method2", that "thread1" is waiting in "Method1" or "Method2"
The logic will work. But not sure what you're trying to ask here.
I have a Class(call it 'Foo') that has a System.Timers.Timer(call it 'myTimer').
Foo wraps unmanaged non thread-safe code.
On myTimer.Elapsed I need to use Methods in Foo.
Right now myTimer is trying use Foo's Methods on worker threads and this isn't working.
I need to get back to the thread that contains Foo' Methods.
How do I accomplish this?
FYI, Foo's Methods are in a non-UI thread.
If Foo is not a UI thread and you need to invoke code to execute on it from a different thread you will need to capture the synchronization context which executes Foo and then invoke your code from the timer on it.
Take a look at the SynchronizationContext class. You can either Post (asynchronously) or Send a delegate to be executed on a specific, previously captured, synchronization context.
You may also want/need to look into the ExecutionContext class. In particular: ExecutionContext.Capture and ExecutionContext.Run
A C#-method is calling on the main-thread after event raising. Then an another event is firing this same method during the first event is busy with the same method. So during debugging, I see in the calling stack two line in the same method on the same thread.
How can I hinder that the second event waits until the first event is ready with the same method. I'm trying with lock() but it doesn't block the same thread. AutoResetEvent can wait but will be waiting on the same thread.
Somebody has the tip? Thanks.
Your problem is caused by Application.DoEvents(). This method does have its uses but it is dangerous, you stumbled onto one of the reasons : re-entrant calls to events.
So, try
remove and avoid DoEvents().
or make all your eventhandlers capable of or resistant to re-entrancy. Take a critical look at what scenarios are possible with the close button for instance. A simple trick could be:
private bool busy = false;
private void MyHandler(sender s, EventArgs e)
{
if (busy)
return; // giving up, no queuing
busy = true;
// code
busy = false; // maybe in a finally clause
}
You can mark the method with MethodImplAttribute attribute.
Example:
[MethodImpl(MethodImplOptions.Synchronized)]
void Method()
{
....
}
Documentation (MSDN):
MethodImplOptions.Synchronized
Specifies that the method can be executed by only one thread at a time. Static methods lock on the type, whereas instance methods lock on the instance. Only one thread can execute in any of the instance functions, and only one thread can execute in any of a class's static functions.
I have a rather large class which contains plenty of fields (10+), a huge array (100kb) and some unmanaged resources. Let me explain by example
class ResourceIntensiveClass
{
private object unmaganedResource; //let it be the expensive resource
private byte[] buffer = new byte[1024 * 100]; //let it be the huge managed memory
private Action<ResourceIntensiveClass> OnComplete;
private void DoWork(object state)
{
//do long running task
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}
public void Start(object dataRequiredForCurrentTask)
{
ThreadPool.QueueUserWorkItem(DoWork); //initiate long running work
}
}
The problem is that the start method never returns after the 10000th iteration causing a stack overflow. I could execute the OnComplete delegate in another thread giving a chance for the Start method to return, but it requires using extra cpu time and resources as you know. So what is the best option for me?
Is there a good reason for doing your calculations recursively? This seems like a simple loop would do the trick, thus obviating the need for incredibly deep stacks. This design seems especially problematic as you are relying on main() to setup your recursion.
recursive methods can get out of hand quite fast. Have you looked into using Parallel Linq?
you could do something like
(your Array).AsParallel().ForAll(item => item.CallMethod());
you could also look into the Task Parallel Library (TPL)
with tasks, you can define an action and a continue with task.
The Reactive Framework (RX) on the other hand could handle these on complete events in an async manner.
Where are you changing the value of taskData so that its length can ever equal currentTaskIndex? Since the tasks you are assigning to the data are never changing, they are being carried out forever...
I would guess that the problem arises from using the pre-increment operator here:
if(c.CurrentCount < 10000)
c.Start(++c.CurrentCount);
I am not sure of the semantics of pre-increment in C#, perhaps the value passed to a method call is not what you expect.
But since your Start(int) method assigns the value of the input to this.CurrentCount as it's first step anyway, you should be safe replacing this with:
if(c.CurrentCount < 10000)
c.Start(c.CurrentCount + 1);
There is no point in assigning to c.CurrentCount twice.
If using the threadpool, I assume you are protecting the counters (c.CurrentCount), otherwise concurrent increments will cause more activity, not just 10000 executions.
There's a neat tool called a ManualResetEvent that could simplify life for you.
Place a ManualResetEvent in your class and add a public OnComplete event.
When you declare your class, you can wire up the OnComplete event to some spot in your code or not wire it up and ignore it.
This would help your custom class to have more correct form.
When your long process is complete (I'm guessing this is in a thread), simply call the Set method of the ManualResetEvent.
As for running your long method, it should be in a thread that uses the ManualResetEvent in a way similar to below:
private void DoWork(object state)
{
ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(
() => {
//do long running task
mre.Set();
);
thread1.IsBackground = true;
thread1.Name = "Screen Capture";
thread1.Start();
mre.WaitOne();
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}
I have some doubts on executing the following :
public class Test
{
delegate int TestDelegate(string parameter);
static void Main()
{
TestDelegate d = new TestDelegate(PrintOut);
d.BeginInvoke("Hello", new AsyncCallback(Callback), d);
// Give the callback time to execute - otherwise the app
// may terminate before it is called
Thread.Sleep(1000);
Console.ReadKey(true);
}
static int PrintOut(string parameter)
{
Console.WriteLine(parameter);
return 5;
}
static void Callback(IAsyncResult ar)
{
TestDelegate d = (TestDelegate)ar.AsyncState;
Console.WriteLine("Delegate returned {0}", d.EndInvoke(ar));
}
}
1 ) The TestDelegate already pointing to a Method ( "PrintOut").Why do Again we are passing another method ("callback") in d.BeginInvoke("Hello",new AysncCallback(Callback),d);.Does it mean d.BeginInvoke executes "PrintOut" and "Callback" parallely?.Can you please explain line by line what exactly going on?
2) Normally, Aysnchronous execution means the execution of a "thread" is not predictable
or fastest execution ?
3) TestDelegate d = (TestDelegate)ar.AsyncState;
"TestDelegate" d is a delegate.How is it possible to cast it to filed or property? ( ar.AsyncState )
4) can you provide me some live example where do i need to use this Asynchronous execution?
1 ) The TestDelegate already pointing to a Method ( "PrintOut").Why do Again we are passing another method ("callback") in d.BeginInvoke("Hello",new AysncCallback(Callback),d);.Does it mean d.BeginInvoke executes "PrintOut" and "Callback" parallely?.Can you please explain line by line what exactly going on?
PrintOut and Callback are not executed in paralled. Callback will be called when PrintOut has finished and returned.
2) Normally, Aysnchronous execution means the execution of a "thread" is not predictable or fastest execution ?
No. Asynchronous execution means the execution is not synchronous. That is.. the timing and execution time of the execution are not related to the timing of the piece of code that starts the asynchronous operation. It is the opposite of synchronous execution. With synchronous operation you would expect the execution to complete before the next statement is executed. For example, calling another method directly is synchronous operation, or another example is calling a function on a remote service and waiting for it to return before continuing.
3) TestDelegate d = (TestDelegate)ar.AsyncState; "TestDelegate" d is a delegate.How is it possible to cast it to filed or property? ( ar.AsyncState )
The delegate is not being case to a field or property. The cast is the other way around. The field or property is being cast into a TestDelegate.
4) can you provide me some live example where do i need to use this Asynchronous execution?
An example might be if you have a user interface that displays reports. The report might need to be generated from data in a database and takes a long time to generate. You would want to generate the report asynchronously so that the user interface can carry on running. If the report was not generated asynchronously the user interface might appear to be frozen and the user might think the program has crashed.
PrintOut is the function that will be executed on a thread from the thread pool and is the function your delegate is pointing to. Callback is the function that will be executed once PrintOut finishes and in which you have to call the EndXXX method which will give you the result of the PrintOut execution. These two functions are not executed in parallel. Here's line by line:
Create a delegate pointing to the PrintOut method
Draw a thread from the thread pool (if available) and run the PrintOut method on this thread by passing "Hello" as argument.
In the meantime the main thread sleeps for 1 second
Once the PrintOut method finishes executing, the Callback method is called. This is where you handle the result of the asynchronous operation.
As far as the casting is concerned: AsyncState is an object, a delegate in .NET is also an object, so no problem casting.
1) Callback will be called by the runtime after PrintOut is executed.
2) Yes, it is not predictable. BeginInvoke makes code to execute on thread from pool, so real performance depends on many parameters, such as thread usage in other places of your program.
3) Delegates are objects. So, reference to them can be casted to object and backward. In case of IAsyncResult returned by BeginInvoke, AsyncState stores delegate, to make proper result extraction possbile.
4) A fragment from a program opening turnstile and making indication (both are time consuming) after user authentication:
if(user.Id.HasValue)
{
Action openDoor = turnstile.Open;
Action<LedColor> indicate = led.SetColor;
// starting async operations
openDoor.BeginInvoke(openDoor.EndInvoke, null);
indicate.BeginInvoke(LedColor.Green, indicate.EndInvoke, null);
// main thread activity.
MakeRecordToLog();
}
1) The callback gets called after your work (PrintOut) has finished. You can pass also a null value.
2) Aysnchronous execution means that your code runs on another thread than the main thread of the application.
3) ar.AsyncState is set to the value you passed in the 3rd parameter of the BeginInvoke method.
4) Check out this: http://shiman.wordpress.com/2008/09/10/c-net-delegates-asynchronous-invocation-begininvoke-method/