How to call Soap/mtom web service asynchronously from C# winform - c#

I am attempting to call/push a semi-large tiff and a Gal file to a java webservice.
The platform is Visual Studio 2013, C# windows forms application.
I am pointing to the WSDL file and "The Platform" is generating a service reference class for me.
This is all very abstracted from me, which is a good thing as I am a relative newbie to this arena.
I left the "Generate Task based Code" checked and I get an addSample and addSampleAsync method.
I populate the class fields and push the code up.
The addSample code works fine but blocks the UI.
The async code, addSampleAsync, also works, bit is slower and is not completely asynchronous.
addSampleAsync locks the UI for about half of the processing time and the function call to fncTestUpload does not return for that same period of time.
//Dimensioned at class level
//private static addSamplePortClient Service = new addSamplePortClient();
//private static addSampleResponse Myresult = new addSampleResponse();
//ThisRequest is the WSDL modeled class object.
//This code works, but is slow, 30 seconds on wifi
ResponseType Myresult = Service.addSample(ThisRequest.Request);
MessageBox.Show(Myresult.Message + Myresult.Code);
//This code locks up the UI for about 15 - 20 seconds then takes another 15 to display the messagebox
fncTestUpload(ThisRequest);
async void fncTestUpload(addSampleRequest SentRequest)
{
Myresult = await Service.addSampleAsync(SentRequest.Request);
MessageBox.Show(Myresult.Response.Message + " - " + Myresult.Response.Code);
}
I made the response object a class level variable in hopes of doing something with it in the function that calls fncTestUpload, which it thought would return immediately when calling an Async function. It does not return until after 15 seconds.??
I have spent several hours googling this and have not found any answers as to why the addSampleAsync is not working as advertised.
Microsoft's tutorials may as well be written in Dilbert's Elbonian. I can't follow them and don't find them helpful, so please don't direct me to one.

When you use the 'await' keyword in your method you are saying "Ok, you go ahead and do work, I will return to my caller, let me know when you're done".
So the 15 seconds of waiting is the time it takes your service to process the request, then invoking the state machine generated by the async method to return to the method after the previously awaited method has finished. That is the normal behavior for await.
About the MessageBox that is taking 15 seconds, it could be that the Response property is lazyloading and actually trying to load the code / message for the first time wheb you access those properties.

Related

AWS X-Ray shows absurdly long invoke time for P2P lambda call

So I have a lambda that makes a point-to-point call to another lambda. We have AWS X-Ray set up so we can monitor performance. However, X-Ray show this odd result where even though the invocation itself takes only a second, the "invoke" call from the original takes a minute and a half.
This makes no sense, since we are calling the lambda as an event (ACK and forget) and using an async call on which we do not await. It really causes problems because even though all lambdas successfully complete and do their work (as we can see from Cloudwatch logs and resulting data in our data store), occasionally that secondary lambda call takes so long that X-Ray times out, which bombs the whole rest of the trace.
Other notes:
We have Active tracing enabled on both lambdas
We do occasionally have cold start times, but as you can see from the screenshot, there is no "initialization" step here, so both lambdas are warm
This particular example was a singular action with no other activity in the system, so it's not like there was a bottleneck due to high load
Does anyone have an explanation for this, and hopefully what we can do to fix it?
Our invocation code (simplified):
var assetIds = new List<Guid> { Guid.NewGuid() };
var request= new AddBulkAssetHistoryRequest();
request.AssetIds = assetIds.ToList();
request.EventType = AssetHistoryEventTypeConstants.AssetDownloaded;
request.UserId = tokenUserId.Value;
var invokeRequest = new InvokeRequest
{
FunctionName = "devkarl02-BulkAddAssetHistory",
InvocationType = InvocationType.Event,
Payload = JsonConvert.SerializeObject(request)
};
var region = RegionEndpoint.GetBySystemName("us-east-1");
var lambdaClient= new AmazonLambdaClient(region)
_ = lambdaClient.InvokeAsync(invokeRequest);
This is also posted over in the AWS Forums (for whatever that is worth): https://forums.aws.amazon.com/thread.jspa?threadID=307615
So it turns out the issue was that we weren't using the await operator. For some reason, that made the calls interminably slow. Making this small change:
_ = await lambdaClient.InvokeAsync(invokeRequest);
made everything else behave properly, both in logs and in x-ray. Not sure why, but hey, it solved the issue.
As far as I understand, not adding the await, causes the call to execute synchronously while adding the await causes the call to happen async.

task.factory.startnew thread cancel with another comming request

i have a web service with just one method. the web service is working so simple. here is the part of my web service code:
//submit transaction(s) into the database
Simpay simpay = new Simpay { Account = account, Job = new SystemJob { ID = 0, TypeName = "SimpayHistory" } };
Task.Factory.StartNew<bool>(simpay.AddHistory);
as you can see Im using the Task.Factory.StartNew in order to do the task in another thread. but sometimes something wired happens. lets assume task factory take the thread number 300 and start doing its job. suddenly another request comes and it took the same thread!! so my first task just cancel!!(I'm not sure about it but its the only thing that i found in my logs!)
now i wonder is this possible? how can i avoid this?
here is part of my log file. as you can see another request comes and take the old one thread!!!(first line belong to the Task factory and second one belongs to the new request. thread number is 345)
[DEBUG];[2015-11-05 07:37:57,526];[345];[DataBase.Query line:56];[2.5646];[];[(Stored Procedure: ud_prc_simPayRetrieveLastTransaction)(Code: 1)(Message: No Error.)(SQL Parameters: #mobileNumber)]
[INFO ];[2015-11-05 07:37:57,667];[345];[Identity.DoesUserNameContentValid line:146];[0.0591];[];[(Message: user name content validation completed successfully.)]
What you are experiencing is what Job Skeet describes as re-entrance. I must refer you to his post here. He gives an in depth explanation of it.
A short answer is that it is possible for future executions of tasks to hijack existing ones and kill out their processes.

MVC 5 / .NET 4.5 - Long running process

I have a website on Rackspace which does calculation, the calculation can take anywhere from 30 seconds to several minutes. Originally I implemented this with SignalR but had to yank it due to excessive CC usage. Hosted Rackspace sites are really not designed for that kind of use. The Bill went though the roof.
The basic code is as below which work perfectly on my test server but of course gets a timeout error on Rackspace if the calculation take more than 30 seconds due to their watcher killing it. (old code) I have been told that the operation must write to the stream to keep it alive. In the days of old I would have started a thread and polled the site until the thread was done. If there is a better way I would prefer to take it.
It seems that with .NET 4.5 I can use the HttpTaskAsyncHandler to accomplish this. But I'm not getting it. The (new code) below is as I understand the handler you would use by taking the old code in the using and placing it in the ProcessRequestAsync task. When I attempt to call the CalcHandler / Calc I get a 404 error which most likely has to do with routing. I was trying to follow this link but could not get it to work either. The add name is "myHandler" but the example link is "feed", how did we get from one to the other. They mentioned they created a class library but can the code be in the same project as the current code, how?
http://codewala.net/2012/04/30/asynchronous-httphandlers-with-asp-net-4-5/
As a side note, will the HttpTaskAsyncHandler allow me to keep the request alive until it is completed if it takes several minutes? Basically should I use something else for what I am trying to accomplish.
Old code
[Authorize]
[AsyncTimeout(5000)] // does not do anything on RackSpace
public async Task<JsonResult> Calculate(DataModel data)
{
try
{
using (var db = new ApplicationDbContext())
{
var result = await CalcualteResult(data);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
LcDataLink.ProcessError(ex);
}
return Json(null, JsonRequestBehavior.AllowGet);
}
new code
public class CalcHandler : HttpTaskAsyncHandler
{
public override System.Threading.Tasks.Task ProcessRequestAsync(HttpContext context)
{
Console.WriteLine("test");
return new Task(() => System.Threading.Thread.Sleep(5000));
}
}
It's not a best approach. Usually you need to create a separate process ("worker role" in Azure).
This process will handle long-time operations and save result to the database. With SignalR (or by calling api method every 20 seconds) you will update the status of this operation on client side (your browser).
If this process takes too much time to calculate, your server will become potentially vulnerable to DDoS attacks.
Moreover, it depends on configuration, but long-running operations could be killed by the server itself. By default, if I'm not mistaken, after 30 minutes of execution.

SharePoint 2013: SPLongOperation timing out

Currently I'm experiencing an issue with SPLongOperation in SharePoint 2013. I have some custom logic which takes at least 15 minutes to process and therefore I use a SPLongOperation to make sure it's not timing out after 6 minutes. In the past this piece of code worked on SharePoint 2010. The problems is that the code execution stops exactly after 6 minutes. With debugger attached it doesn't timeout, so somehow the SPLongOperation block is ignored or not working correctly. The code I use to call the SPLongOperation is as follows:
using (SPLongOperation operation = new SPLongOperation(Page))
{
try
{
operation.LeadingHTML = html; //adding some custom html...
operation.Begin();
// Business Logic
}
finally
{
operation.End("/page.aspx", SPRedirectFlags.RelativeToLayoutsPage, Context, string.Empty);
}
}
The behavior I see at several machines with this piece of code is that after 6 minutes a Timeout occurs with the following exception in ULS:
System.Web.HttpException: Request timed out. Has anyone an idea what might be the problem? I'm using SharePoint 2013 with October CU installed on it. I also tested this block using a while(true) statement to make sure the business logic is not causing the problem.
Also have this problem, found this approach, define the timeout for the page, before creation SPLongOp object:
Page.Server.ScriptTimeout = 3600; // specify the timeout to 3600 seconds
using (SPLongOperation operation = new SPLongOperation ( this .page))
{
}
Source: http://shaharpan.wordpress.com/2014/11/20/splongoperation-thread-was-being-aborted-error-in-sharepoint-2013/
Tomas
SPLongOperation keeps a connection between client and server open while executing. Its purpose is to inform a user that everything is OK, but it takes a little time (2-3 minutes) to finish whatever is to be finished.
So if you need to run a really long procedure (e.g., lasting for 1 hour) you need to use other ways, timer jobs, for instance.

Why is AsyncController grinding my server to a halt?

I recently made some (fairly trivial) changes to one of my ASP.NET MVC3 controllers and changed one of the actions into an async action. Basically I took code that looks like this:
public ActionResult MyAction(BindingObject params){
// use HttpWebRequest to call an external API and process the results
}
And turned it into code that looks like this:
private delegate ActionResult DoMyAction(BindingObject params);
public void MyActionAsync(BindingObject params){
AsyncManager.OutstandingOperations.Increment();
var doMyAction = new DoMyAction(MyAction);
doMyAction.BeginInvoke(params, MyActionCallback, doMyAction);
}
private void MyActionCallback(IAsyncResult ar){
var doMyAction = ar.AsyncState as DoMyAction;
AsyncManager.Parameters["result"] = doMyAction != null ? doMyAction.EndInvoke(ar) : null;
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult MyActionCompleted(ActionResult result){
return result;
}
private ActionResult MyAction(BindingObject params){
// use HttpWebRequest to call an external API and process the results
}
This seems to work fine, when I test it locally calling MyAction, breakpoints in each of the methods fire when I would expect them to and it ultimately returns the expected result.
I would anticipate this change to at best improve performance under heavy load because now my worker threads aren't being eaten up waiting for the HttpWebRequest to call the external API, and at worst have no effect at all.
Before pushing this change, my server's CPU usage averaged around 30%, and my W3SVC_W3WP Active Requests perfmon stat hovers around 10-15. The server is Win Server 2008 R2 and the MVC site gets around 50 requests per second.
Upon pushing this change, the CPU shoots up to constant 90-100% usage, and the W3SVC_W3WP Active Requests counter slowly increases until it hits the maximum of 5000 and stays there. The website becomes completely unresponsive (either timing out or giving "Service Unavailable" errors).
My assumption is I'm either implementing the AsyncController incorrectly, missing some additional configuration that's required, or maybe just misunderstanding what the AsyncController is supposed to be used for. In any case, my question is why is this happening?
By async-invoking a delegate you move the work to the thread pool. You still burn a thread. You gain nothing and loose performance.
Async mostly makes sense when you can trigger true async IO.

Categories

Resources