This is the program output:
Program Begin
1 - Starting
2 - Task started
A - Started something
Program End
B - Completed something
3 - Task completed with result: 123
Question: As far i understand when it comes to await process is going back to main context so in this case to Main and then go back to await when it's finished so "A - Started something" should be after "Program End". Why this one line was shown? From my understanding when it comes to away it should immediatly go back to main context.
static void Main(string[] args)
{
Console.WriteLine("Program Begin");
DoAsAsync();
Console.WriteLine("Program End");
Console.ReadLine();
}
static async void DoAsAsync()
{
Console.WriteLine("1 - Starting");
var t = Task.Factory.StartNew<int>(DoSomethingThatTakesTime);
Console.WriteLine("2 - Task started");
var result = await t;
Console.WriteLine("3 - Task completed with result: " + result);
}
static int DoSomethingThatTakesTime()
{
Console.WriteLine("A - Started something");
Thread.Sleep(1000);
Console.WriteLine("B - Completed something");
return 123;
}
As far i understand when it comes to await process is going back to main context so in this case to Main and then go back to await when it's finished so "A - Started something" should be after "Program End".
That is what that thread is doing; the main thread is returning to the Main method.
However, StartNew will (in this case) execute its work on a thread pool thread, which runs independently from the main thread. So, you might see "A - Started something" before or after "Program End".
When it comes to await, first the task get triggered, here it is "DoSomethingThatTakesTime". And then goes back to calling method to perform the next task/execution (here in your case it is Main()).
This will be much meaning full if you have another await in the main.
look into below example. very well explained.
https://msdn.microsoft.com/en-us/library/mt674892.aspx
You may see a different result, if you call thread sleep before first print statement.
Related
I have to instrument any given code (without directly changing given code ) at the beginning and end of every thread. Simply speaking , how can I print something at entry and exit points of any thread.
How can I do that using javassist ?
Short Answer
You can do this by creating an ExprEditor and use it to modify MethodCalls that match with start and join of thread objects.
(very) Long answer (with code)
Before we start just let me say that you shouldn't be intimidated by the long post, most of it is just code and once you break things down it's pretty easy to understand!
Let's get busy then...
Imagine you have the following dummy code:
public class GuineaPig {
public void test() throws InterruptedException {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++)
System.out.println(i);
}
});
t.start();
System.out.println("Sleeping 10 seconds");
Thread.sleep(10 * 1000);
System.out.println("Done joining thread");
t.join();
}
}
When you run this code doing
new GuineaPig().test();
You get an output like (the sleeping system.out may show up in the middle of the count since it runs in the main thread):
Sleeping 10 seconds
0
1
2
3
4
5
6
7
8
9
Done joining thread
Our objective is to create a code injector that will make the output change for the following:
Detected thread starting with id: 10
Sleeping 10 seconds
0
1
2
3
4
5
6
7
8
9
Done joining thread
Detected thread joining with id: 10
We are a bit limited on what we can do, but we are able to inject code and access the thread reference. Hopefully this will be enough for you, if not we can still try to discuss that a bit more.
With all this ideas in mind we create the following injector:
ClassPool classPool = ClassPool.getDefault();
CtClass guineaPigCtClass = classPool.get(GuineaPig.class.getName());
guineaPigCtClass.instrument(new ExprEditor() {
#Override
public void edit(MethodCall m) throws CannotCompileException {
CtMethod method = null;
try {
method = m.getMethod();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String classname = method.getDeclaringClass().getName();
String methodName = method.getName();
if (classname.equals(Thread.class.getName())
&& methodName.equals("start")) {
m.replace("{ System.out.println(\"Detected thread starting with id: \" + ((Thread)$0).getId()); $proceed($$); } ");
} else if (classname.equals(Thread.class.getName())
&& methodName.equals("join")) {
m.replace("{ System.out.println(\"Detected thread joining with id: \" + ((Thread)$0).getId()); $proceed($$); } ");
}
}
});
guineaPigCtClass
.writeFile("<Your root directory with the class files>");
}
So what's happening in this small nifty piece of code? We use an ExprEdit to instrument our GuineaPig class (without doing any harm to it!) and intercept all method calls.
When we intercept a method call, we first check if the declaring class of the method is a Thread class, if that's the case it means we are invoking a method in a Thread object. We then proceed to check if it's one of the two particular methods start and join.
When one of those two cases happen, we use the javassist highlevel API to do a code replacement. The replacement is easy to spot in the code, the actual code provided is where it might be a bit tricky so let's split one of those lines, let's take for example the line that will detect a Thread starting:
{ System.out.println(\"Detected thread starting with id: \" + ((Thread)$0).getId()); $proceed($$); } "
First all the code is inside curly brackets, otherwise javassist won't accept it
Then you have a System.out that references a $0. $0 is a special parameter that can be used in javassist code manipulations and represents the target object of the method call, in this case we know for sure it will be a Thread.
$proceed($$) This probably is the trickiest instruction if you're not familiar with javassist since it's all javassist special sugar and no java at all. $proceed is the way you have to reference the actual method call you are processing and $$ references to the full argument list passed to the method call. In this particular case start and join both will have this list empty, nevertheless I think it's better to keep this information.
You can read more about this special operators in Javassist tutorial, section 4.2 Altering a Method Body (search for MethodCall subsection, sorry there's no anchor for that sub-section)
Finally after all this kung fu we write the bytecode of our ctClass into the class folder (so it overwrites the existing GuinePig.class file) and when we execute it... voila, the output is now what we wanted :-)
Just a final warning, keep in mind that this injector is pretty simple and does not check if the class has already been injected so you can end up with multiple injections.
I am using async action methods:
public async Task<JsonResult> SetMaterialRequisitionNoteStatus(List<Guid> ids, string statusName, Guid statusId)
{
string resp = string.Empty;
resp = await note.GeneratePartLifeNotifications_ORN(repairNote, "Outsourced Repair Note " + statusName);
if (responce.ToLower() != "ok")
{
responce = responce.Replace("Workorder", "Outsource repair note");
sendNotification(responce);
}
Utilities.SaveEntityInstance(note);
......
}
But my code is not working asynchronously. The line next to await calls wait until we get the result from GeneratePartLifeNotifications_ORN method.
It is working as same synchronous code.
I want asynchronous behaviour.
The line next to await calls wait until we get the result from
generatePartLifeNotifications_ORN method.
Well, what did you expect? await will execute that method asynchronously and will release the current thread for doing work somewhere else. When that asynchronous task is completed, the thread will comeback to pick the function execution from there with the result (unless you specify .ConfigureAwait(false), then any thread could pick the execution).
"Await" means something like "wait for", so the execution is waiting for that method to complete, but the thread left to work in something else and it is not waiting.
If you executed this in a synchronous fashion, the execution order will be the same, but the calling thread will be blocked waiting for GeneratePartLifeNotifications_ORN to finish. The magic of async, is to allow threads to working in something else instead of waiting for things that are happening away (like a webservice, or a database).
Cheers.
while debugging the java Multithreading program i put breakpoints. after start method is invoking the control is not going to run menthod can you please let me know the debug procedure.
sample code
class Test extends Thread {
public static void main(String[] args) {
try {
Thread t = new Thread(new Test());
t.start();
t.start();
} catch (Exception e) {
System.out.print("e ");
}
}
public void run() {
for(int i = 0; i < 2; i++)
System.out.print(Thread.currentThread().getName() + " ");
}
}
Debugger starts with main thread, since your breakpoint is in main thread.
t.start() spawns a new thread.
But the debugger will continue with the main thread itself.
If you want to debug the newly created thread, then you have to set a breakpoint in run() method also.Then the debugger control goes to the newly created thread, but it is invisible to the user.
If you want to see the control in run() method of newly created thread, then you have to follow the below steps -
Put a breakpoint in run() method along with the main() method.
Start debugging the program till you hit the statement t.start().
After completing t.start(), go to "Debug" view. There you will find 2 threads running.(You can find the "Debug" view in eclipse by going to "Window -> Show View -> Debug").
First one is main thread
Second one is newly created thread (e.g. [Thread-1] )
Click on the second thread to see the control in run method.
After completion of your thread execution, go to the "Debug" view again and click on the main thread to continue with the main thread debugging.
Note: If you continue with the main thread after 3rd step towards the end of the thread, then you will not be able to debug your new thread.
I have a web service in WCF that consume some external web services, so what I want to do is make this service asynchronous in order to release the thread, wait for the completion of all the external services, and then return the result to the client.
With Framework 4.0
public class MyService : IMyService
{
public IAsyncResult BeginDoWork(int count, AsyncCallback callback, object serviceState)
{
var proxyOne = new Gateway.BackendOperation.BackendOperationOneSoapClient();
var proxyTwo = new Gateway.BackendOperationTwo.OperationTwoSoapClient();
var taskOne = Task<int>.Factory.FromAsync(proxyOne.BeginGetNumber, proxyOne.EndGetNumber, 10, serviceState);
var taskTwo = Task<int>.Factory.FromAsync(proxyTwo.BeginGetNumber, proxyTwo.EndGetNumber, 10, serviceState);
var tasks = new Queue<Task<int>>();
tasks.Enqueue(taskOne);
tasks.Enqueue(taskTwo);
return Task.Factory.ContinueWhenAll(tasks.ToArray(), innerTasks =>
{
var tcs = new TaskCompletionSource<int>(serviceState);
int sum = 0;
foreach (var innerTask in innerTasks)
{
if (innerTask.IsFaulted)
{
tcs.SetException(innerTask.Exception);
callback(tcs.Task);
return;
}
if (innerTask.IsCompleted)
{
sum = innerTask.Result;
}
}
tcs.SetResult(sum);
callback(tcs.Task);
});
}
public int EndDoWork(IAsyncResult result)
{
try
{
return ((Task<int>)result).Result;
}
catch (AggregateException ex)
{
throw ex.InnerException;
}
}
}
My questions here are:
This code is using three threads: one that is instanced in the
BeginDoWork, another one that is instanced when the code enter
inside the anonymous method ContinueWhenAll, and the last one when
the callback is executed, in this case EndDoWork. Is that correct or
I’m doing something wrong on the calls? Should I use any
synchronization context? Note: The synchronization context is null
on the main thread.
What happen if I “share” information between
threads, for instance, the callback function? Will that cause a
performance issue or the anonymous method is like a closure where I
can share data?
With Framework 4.5 and Async and Await
Now with Framework 4.5, the code seems too much simple than before:
public async Task<int> DoWorkAsync(int count)
{
var proxyOne = new Backend.ServiceOne.ServiceOneClient();
var proxyTwo = new Backend.ServiceTwo.ServiceTwoClient();
var doWorkOne = proxyOne.DoWorkAsync(count);
var doWorkTwo = proxyTwo.DoWorkAsync(count);
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return doWorkOne.Result + doWorkTwo.Result;
}
But in this case when I debug the application, I always see that the code is executed on the same thread. So my questions here are:
3.. When I’m waiting for the “awaitable” code, is that thread released and goes back to the thread pool to execute more requests?
3.1. If So, I suppose that when I get a result from the await Task, the execution completes on the same thread that the call before. Is that possible? What happen if that thread is processing another request?
3.2 If Not, how can I release the thread to send it back to the thread pool with Asycn and Await pattern?
Thank you!
1. This code is using three threads: one that is instanced in the BeginDoWork, another one that is instanced when the code enter inside the anonymous method ContinueWhenAll, and the last one when the callback is executed, in this case EndDoWork. Is that correct or I’m doing something wrong on the calls? Should I use any synchronization context?
It's better to think in terms of "tasks" rather than "threads". You do have three tasks here, each of which will run on the thread pool, one at a time.
2. What happen if I “share” information between threads, for instance, the callback function? Will that cause a performance issue or the anonymous method is like a closure where I can share data?
You don't have to worry about synchronization because each of these tasks can't run concurrently. BeginDoWork registers the continuation just before returning, so it's already practically done when the continuation can run. EndDoWork will probably not be called until the continuation is complete; but even if it is, it will block until the continuation is complete.
(Technically, the continuation can start running before BeginDoWork completes, but BeginDoWork just returns at that point, so it doesn't matter).
3. When I’m waiting for the “awaitable” code, is that thread released and goes back to the thread pool to execute more requests?
Yes.
3.1. If So, I suppose that when I get a result from the await Task, the execution completes on the same thread that the call before. Is that possible? What happen if that thread is processing another request?
No. Your host (in this case, ASP.NET) may continue the async methods on any thread it happens to have available.
This is perfectly safe because only one thread is executing at a time.
P.S. I recommend
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return result[0] + result[1];
instead of
var result = await Task.WhenAll(doWorkOne, doWorkTwo);
return doWorkOne.Result + doWorkTwo.Result;
because Task.Result should be avoided in async programming.
I have a question regarding the sequencing of events in the scenario where you are calling a wcf service from silverlight 3 and updating the ui on a seperate thread. Basically, I would like to know whether what I am doing is correct... Sample is as follows. This is my first post on here, so bear with me, because i am not sure how to post actual code. Sample is as follows :
//<summary>
public static void Load(string userId)
{
//Build the request.
GetUserNameRequest request =
new GetUserNameRequest { UserId = userId };
//Open the connection.
instance.serviceClient = ServiceController.UserService;
//Make the request.
instance.serviceClient.GetUserNameCompleted
+= UserService_GetUserNameCompleted;
instance.serviceClient.GetGetUserNameAsync(request);
return instance.VM;
}
/// <summary>
private static void UserService_GetUserNameCompleted(object sender, GetUserNameCompletedEventArgs e)
{
try
{
Controller.UIDispatcher.BeginInvoke(() =>
{
//Load the response.
if (e.Result != null && e.Result.Success)
{
LoadResponse(e.Result);
}
//Completed loading data.
});
}
finally
{
instance.serviceClient.GetUserNameCompleted
-= UserService_GetUserNameCompleted;
ServiceHelper.CloseService(instance.serviceClient);
}
}
So my question basically is, inside of my UI thread when I am loading the response if that throws an exception, will the "finally" block catch that ? If not, should i put another try/catch inside of the lambda where I am loading the response ?
Also, since I am executing the load on the ui thread, is it possible that the finally will execute before the UI thread is done updating ? And could as a result call the Servicehelper.CloseService() before the load has been done ?
I ask because I am having intermittent problems using this approach.
The finally block should get executed before the processing of the response inside the BeginInvoke. BeginInvoke means that the code will get executed in the next UI cycle.
Typically the best approach to this type of thing is to pull all the data you need out of the response and store it in a variable and then clean up your service code. Then make a call to BeginInvoke and update the UI using the data in the variable.