Multi-threading synchronization using wide scope lock with WCF callbacks - c#

What I want to do is this--
I want to make a proxy call to a service and receive data on a separate thread through an asynchronous callback...the tricky part is that I want to make the foreground thread sleep until all of the data has been retrieved.
The reason I'm not using a synchronous method to do this, is because I'm creating an API for a WCF service that uses Paging and returns data in chunks.
I want my client to be able to use Paging, but I don't want to expose all of my Paging callbacks to my API...I want it to appear as though the API exposes a synchronous data retrieval method.
I've tried using a private static Semaphore (because it is thread agnostic,) that is accessible to the class methods and the callbacks, with a single unit capacity as a means to pause the execution.
First, I use a Semaphore.WaitOne() statement.
Then, I do a Proxy call in the foreground thread, and the service creates a thread that handles the data retrieval, and control is passed back to the client.
In the client, I immediately use a second Semaphore.WaitOne() statement.
This should pause the foreground thread execution, which it does.
Then, once the "Paging Completed" Callback is executed on a separate thread, I use Semaphore.Release()
But the foreground thread never traverses the second Semaphore statement, it stays locked and so the client freezes.
Any ideas what I am doing incorrectly, or is there another locking design that would be more effective?

If what you're trying to accomplish is having the foreground thread wait on data-gathering thread, you may want to consider using Tasks, which would allow you to easily accomplish what you've described here.
System.Threading.Tasks:
http://msdn.microsoft.com/en-us/library/dd235608.aspx
Some code:
Task t = new Task(somethingToDo);
// Fire off the new task
t.Start();
// Wait for the task to finish...
t.Wait();
// Do something else...
Make sure to take a look at the details of t.Wait() in the documentation. There are some exceptions you will want to be ready for, in the event that your task fails.

Related

Do I always need to use async/await?

I wanted to ask you about async/await. Namely, why does it always need to be used? (all my friends say so)
Example 1.
public async Task Boo()
{
await WriteInfoIntoFile("file.txt");
some other logic...
}
I have a Boo method, inside which I write something to files and then execute some logic. Asynchrony is used here so that the stream does not stop while the information is being written to the file. Everything is logical.
Example 2.
public async Task Bar()
{
var n = await GetNAsync(nId);
_uow.NRepository.Remove(n);
await _uow.CompleteAsync();
}
But for the second example, I have a question. Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
why does it always need to be used?
It shouldn't always be used. Ideally (and especially for new code), it should be used for most I/O-based operations.
Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
Asynchronous code is all about freeing up the calling thread. This brings two kinds of benefits, depending on where the code is running.
If the calling thread is a UI thread inside a GUI application, then asynchrony frees up the UI thread to handle user input. In other words, the application is more responsive.
If the calling thread is a server-side thread, e.g., an ASP.NET request thread, then asynchrony frees up that thread to handle other user requests. In other words, the server is able to scale further.
Depending on the context, you might or might not get some benefit. In case you call the second function from a desktop application, it allows the UI to stay responsive while the async code is being executed.
Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
You are correct in the sense that this stream of work cannot proceed, but using async versions allows freeing up the thread to do other work:
I like this paragraph from Using Asynchronous Methods in ASP.NET MVC 4 to explain the benefits:
Processing Asynchronous Requests
In a web app that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making web service calls asynchronous increases the responsiveness of the app. An asynchronous request takes the same amount of time to process as a synchronous request. If a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it's performed synchronously or asynchronously. However during an asynchronous call, a thread isn't blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.
Not sure what you mean by
without its presence it will still be impossible to work further
regarding example 2. As far as I can tell this code gets an entity by id from its repository asynchronously, removes it, then completes the transaction on its Unit of Work. Do you mean why it does not simply remove the entry by id? That would certainly be an improvement, but would still leave you with an asynchronous method as CompleteAsync is obviously asynchronous?
As to your general question, I don't think there is a general concensus to always use async/await.
In your second example there with the async/await keywords you are getting the value of the n variable asynchronously. This might be necessary because the GetNAsync method is likely performing some time-consuming operation, such as querying a database or perhaps you might be calling a webservice downstream, that could block the main thread of execution. By calling the method asynchronously, the rest of the code in the Bar method can continue to run while the query is being performed in the background.
But if in the GetNAsync you are just calling another method locally that is doing some basic CPU bound task then the async is pointless in my view. Aync works well when you are sure you need to wait such as network calls or I/O bound calls that will definitely add latency to your stack.

Is it bad practice to retain control of a Socket BeginXXX thread?

In the example of Socket.BeginReceive() your provided method will be called from a thread-pool thread when the asynchronous operation completes. The assumed behaviour seems to be that you will handle the callback and return, typically having called another async method.
But one could use this as a way to obtain a thread which you then use to manage that socket. Is retaining/monopolising this thread (does this have a proper name) going to cause problems or is it just another worker thread you can use as you want?
Note: I'm aware this isn't the modern paradigm for using Sockets and doesn't scale well

Is it pointless to use Threads inside Tasks in C#?

I know the differences between a thread and a task., but I cannot understand if creating threads inside tasks is the same as creating only threads.
It depends on how you use the multithreaded capabilities and the asynchronous programming semantics of the language.
Simple facts first. Assume you have an initial, simple, single-threaded, and near empty application (that just reads a line of input with Console.ReadLine for simplicity sake). If you create a new Thread, then you've created it from within another thread, the main thread. Therefore, creating a thread from within a thread is a perfectly valid operation, and the starting point of any multithreaded application.
Now, a Task is not a thread per se, but it gets executed in one when you do Task.Run which is selected from a .NET managed thread pool. As such, if you create a new thread from within a task, you're essentially creating a thread from within a thread (same as above, no harm done). The caveat here is, that you don't have control of the thread or its lifetime, that is, you can't kill it, suspend it, resume it, etc., because you don't have a handle to that thread. If you want some unit of work done, and you don't care which thread does it, just that's it not the current one, then Task.Run is basically the way to go. With that said, you can always start a new thread from within a task, actually, you can even start a task from within a task, and here is some official documentation on unwrapping nested tasks.
Also, you can await inside a task, and create a new thread inside an async method if you want. However, the usability pattern for async and await is that you use them for I/O bound operations, these are operations that require little CPU time but can take long because they need to wait for something, such as network requests, and disk access. For responsive UI implementations, this technique is often used to prevent blocking of the UI by another operation.
As for being pointless or not, it's a use case scenario. I've faced situations where that could have been the solution, but found that redesigning my program logic so that if I need to use a thread from within a task, then what I do is to have two tasks instead of one task plus the inner thread, gave me a cleaner, and more readable code structure, but that it's just personal flair.
As a final note, here are some links to official documentation and another post regarding multithreaded programming in C#:
Async in Depth
Task based asynchronous programming
Chaining Tasks using Continuation Tasks
Start multiple async Tasks and process them as they complete
Should one use Task.Run within another Task
It depends how you use tasks and what your reason is for wanting another thread.
Task.Run
If you use Task.Run, the work will "run on the ThreadPool". It will be done on a different thread than the one you call it from. This is useful in a desktop application where you have a long-running processor-intensive operation that you just need to get off the UI thread.
The difference is that you don't have a handle to the thread, so you can't control that thread in any way (suspend, resume, kill, reuse, etc.). Essentially, you use Task.Run when you don't care which thread the work happens on, as long as it's not the current one.
So if you use Task.Run to start a task, there's nothing stopping you from starting a new thread within, if you know why you're doing it. You could pass the thread handle between tasks if you specifically want to reuse it for a specific purpose.
Async methods
Methods that use async and await are used for operations that use very little processing time, but have I/O operations - operations that require waiting. For example, network requests, read/writing local storage, etc. Using async and await means that the thread is free to do other things while you wait for a response. The benefits depend on the type of application:
Desktop app: The UI thread will be free to respond to user input while you wait for a response. I'm sure you've seen some programs that totally freeze while waiting for a response from something. This is what asynchronous programming helps you avoid.
Web app: The current thread will be freed up to do any other work required. This can include serving other incoming requests. The result is that your application can handle a bigger load than it could if you didn't use async and await.
There is nothing stopping you from starting a thread inside an async method too. You might want to move some processor-intensive work to another thread. But in that case you could use Task.Run too. So it all depends on why you want another thread.
It would be pointless in most cases of everyday programming.
There are situations where you would create threads.

Threads, Task, async/await, Threadpool

I am getting really confused here about multithreading :(
I am reading about the C# Async/Await keywords. I often read, that by using this async feature, the code gets executed "non-blocking". People put code examples in two categories "IO-Bound" and "CPU-bound" - and that I should not use a thread when I execute io-bound things, because that thread will just wait ..
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
If I use the Threadpool, an instance of "Thread"-class, delegate.BeginInvoke or the TPL -- every asynchronous execution is done on another thread. (with or without a callback)
What you are missing is that not every asynchronous operation is done on another thread. Waiting on an IO operation or a web service call does not require the creation of a thread. On Windows this is done by using the OS I/O Completion Ports.
What happens when you call something like Stream.ReadAsync is that the OS will issue a read command to the disk and then return to the caller. Once the disk completes the read the notifies the OS kernel which will then trigger a call back to your processes. So there is no need to create a new threadpool thread that will just sit and block.
What is meant is this:
Suppose you query some data from a database (on another server) - you will send a request and just wait for the answer. Instead of having a thread block and wait for the return it's better to register an callback that get's called when the data comes back - this is (more or less) what async/await does.
It will free the thread to do other things (give it back to the pool) but once your data come back asynchronously it will get another thread and continue your code at the point you left (it's really some kind of state-machine that handles that).
If your calculation is really CPU intensive (let's say you are calculating prime-numbers) things are different - you are not waiting for some external IO, you are doing heavy work on the CPU - here it's a better idea to use a thread so that your UI will not block.
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
Not exactly. An operation will take however long it is going to take. When you have a single-user application, running long-running things on a separate thread lets the user interface remain responsive. At the very least this allows the UI to have something like a "Cancel" button that can take user input and cancel processing on the other thread. For some single-user applications, it makes sense to allow the user to keep doing other things while a long-running task completes (for example let them work on one file while another file is uploading or downloading).
For web applications, you do not want to block a thread from the thread pool during lengthy(ish) IO, for example while reading from a database or calling another web service. This is because there are only a limited number of threads available in the thread pool, and if they are all in use, the web server will not be able to accept additional HTTP requests.

Async WCF call to save thread?

In another SO question, I was advised to send an asynchronous network request, rather than sending a synchronous request on a background thread. The reason was so that I don't waste a thread. I'm trying to understand how this is so.
This is the original approach. I can understand how there are two threads here. One is the main thread (1), and one is the background thread (Task.Run) (2) that makes the WCF call:
This is my sketch of the suggested approach. I'm trying to understand how a thread is saved. After the async WCF call, won't another thread be created for the callback from the async WCF call?
After thinking about this further, perhaps only one thread is used if callback processing isn't necessary?
In your WPF client you likely have a OnClick somewhere in your client, where is the thread that is checking if the client was clicked or not?
The answer to that the OS itself is checking for the click then passing the message along to to the message pump which in turn invokes your function. The callback for the WCF function is like that, the OS itself is listening for the reply message and when it gets one it will send a signal that will find a free thread on the thread pool and execute the callback at that time.
The major difference between synchronously holding the thread and letting the callback method generate a thread at the end is the fact that the thread pool is a pool. When a thread in the thread pool finishes its work it does not get destroyed, it waits around a while to see if more work is available to be done and it will be reused to do that new work.
So the two choices are
Have 1 Thread sit there waiting doing no other work waiting for the function to unblock (Sync + thread)
Reuse an existing thread that has finished it's work already (or spawn a new one if none are waiting and we are below ThreadPool.GetMaxThreads()) when the OS tells us the information we where waiting for has shown up, give it the short task of handling the callback, then letting the thread go back in to the pool to do other work for other callbacks as they come in.

Categories

Resources