Multithreaded web service calls in asp.net web forms - c#

I have an aspx page to make calls to a web service, each of which can take up to few minutes and I want to make it work in a multi-threaded way. Basically what I want is when user clicks one of the buttons
I want to make a service call to my web service but I also want user to be able to click the other buttons and make other service calls if they want. and if the later calls
are completed faster than the first one, results must be shown to user without waiting for the result of the first call. (Yo can think about desktop sql editor applications)
However I can't manage this with my current method. The first call always blocks the following ones, I wonder If I can accomplish this
kind of behviour in a web application.
I use a code like the floowing for my service calls:
protected void GetResult_Click(object sender, EventArgs e)
{
ShowSelectData(sql, connStr, tabId);
}
private void ShowSelectData(string sql, string connStr, string tabId)
{
SqlServiceClient cli = new SqlServiceClient();
cli.ShowSelectDataCompleted += cli_ShowSelectDataCompleted;
cli.ShowSelectDataAsync(sql, connStr, tabId);
}
void cli_ShowSelectDataCompleted(object sender, SqlService.ShowSelectDataCompletedEventArgs e)
{
var res = e.Result;
//here I show resullts to user
}
I also add Async="true" to my aspx page

Basically what I want is when user clicks one of the buttons I want to
make a service call to my web service but I also want user to be able
to click the other buttons and make other service calls
What you asked can be accomplished by ajax async call; leave to your client the burden to call the service (by an async call) and manage the response.
When the user click a button make a call to the service; meantime the first call is executing the client can call the second, meantime first and second are executing the client can call the third... the user is not frozen waiting the first call to finish
If you can't call the service directly from a javascript client wrap server side the service calls into rest services and call the rest services from your client.

Related

How can I send the RESTAPI call to all 3 of the GET()/POST() by using the single button click of Submit() button in my WebClient side

Let's say I have a Single Web Page that contains multiple Tab. I don't want user to click save in each tab. I want them to finish edit the data and click Submit only once at the end of their transaction.
My doubt is that for each tab(Order/Customer/Vendor) tabs has their own set of controller(OrdersController, CustomerController & VendorController) and own GET()/POST() methods accordingly in the WebAPI backend.
(From Web Client side)
How can I send the RESTAPI call to all 3 of the GET()/POST() by using the single button click of Submit() button in my WebClient side?
How should I handle back the replyRequest from WebAPI? Should I send multiple call in 1 single Submit button and it will return multiple reply message to web client?
(From Web API side)
What is the best practice to design the WebAPI controller GET()/POST()?
Should I write 3 of the GET()/POST() method in 1 single controller?
Should I continue current design(separate each GET()/POST() method according to DataModel)
To make the life easier you may combine all three methods in three different controllers in one super method and send all the data to that method.
If it is not possible to combine all methods into one, at least all methods should be in one controller and One method may call other methods on the server.
In my opinion there should be one call only from client to server.
What is the best practice to design the WebAPI controller GET()/POST()?
Using common sense!! :)
You may need to make 1 single call that will do everything, and separate the business logic from the API using services:
public IActionResult Save(OrderInput input)
{
_orderService.CreateOrder(new Order{ ... });
_customerService.UpdateBalance(input.CustomerId, input.TotalAmount);
// return whatever you want here...
}

how to retrieve the instance of library which is invoked using navigationservice.service () in wp8

I have created an authentication library in wp8 which requires me to provide a login screen UI and return the session id and other login details on authentication with server.. I have an API which returns the login data..
Now in the app im going to the login screen using NavigationService.navigate () which automatically instantiates my library class..
My Question is how do I get the reference to object of class that is instantiated by navigate method.. Also it seems that navigate() is asynchronous as it shows my login page and immediately moves to the line after the call.. My requirement is that I have to call the API that returns login data only after authentication has been performed but I have no reference of the instantiated object to call it
Is there any way to make the navigate() wait until the authentication is complete?
You are getting username and password from login screen and you are using this data for authentication.then,you can call your API in login screen's "say Login" button and after that you can use event delegate mechanism to receive web service response status, if its correct then you can navigate to next screen,till then you can use ProgressBar.
please check this code to get understanding of await:
Object response = await Authenticate(UsernameTextBox.Text, PasswdTextBox.Password);
if (response is success)//typecast your object as per your need to get status of result
{
Navigate
}
else
{
Show error dialog
}
Also dont forget to modify your button event handler's signature with "async".

Capture Third Party DLL events in WCF

I’ve been supplied with a DLL by a third party which processes the data it’s supplied and returns its results through an event as below.
private IBlackbox blackbox;
// Capture the processed data from the BlackBox
public void blackbox_Processed(object sender, BlackBoxEventArgs e)
{
string returndata = e.ReturnData;
// Do something with the data
}
public void blackbox_Run(string datavalues)
{
blackbox.Processed += new EventHandler(blackbox_Processed);
blackbox = BlackBox.Create(datavalues);
blackbox.Start();
}
This implementation works fine when called from a Windows form with the blackbox.Processed event firing in less than a second. However, when I implement this in a WCF method the blackbox.Processed event is never trapped.
Can anyone help?
It's hard to say for certain since you haven't provided code for your service but my guess is that the call to your service method is returning before your blackbox component fires the event. One thing you could look at would be using a WCF duplex service which would allow you to publish an event from the server to the client.
WCF Duplex Services

How to remove a timer, after a session ends?

I'm implementing an auto-refresh feature on a asp.net website.
The user does the login on the website, and if he goes to a specific page, which has a table that needs to be refreshed, a timer is created that refreshes the table.
But when the user logs out or the session expires, the timer keeps running. Now multiply this for X users, and we will have X timers running on the server.
What's the best way to get rid of the timers when they're no longer needed?
So far my code is the following:
protected static System.Timers.Timer _timer;
protected void Page_Load(object sender, EventArgs e)
{
...
ServiceStatus serv = new ServiceStatus();
OutSubscricoesInfoV2 subscr = new OutSubscricoesInfoV2();
serv = StreamerUtils.GetSubscricoesStreamer(ref subscr);
if (serv != null && serv.success)
{
StreamerUtils.StreamerState strState = StreamerUtils.GetStreamerState(subscr);
if (strState != null && strState.IsActive)
{
startAutoRefresh();
}
}
}
private void startAutoRefresh()
{
if (Session["RefreshTimer"] == null)
{
_timer = new System.Timers.Timer(10000);
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
_timer.Enabled = true;
Session["RefreshTimer"] = _timer;
}
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
//TODO: call refresh function
}
In my page, i have the following button which the user can click to refresh the table:
<asp:ImageButton runat="server" ID="RefreshCot" OnClientClick="javascript:StocksListControl.TriggerPostBack(); return false;" CausesValidation="false" ImageUrl="/_layouts/images/refresh-title.png" />
I agree with the first comment to your question posted by Aristos, this is bad design.
For this situation I would suggest three options:
Use a asp.net Ajax control. An example can be found here: http://www.tutorialspoint.com/asp.net/asp.net_ajax_control.htm
AJAX poling - Have the timers in JavaScript which will sit on the clients. Once the timer has passed its elapsed time, the client will make an AJAX request to the server (preferably calling a web service) to fetch the updated data. I would recommend using a JavaScript library for this such as JQuery. The documentation on their ajax function is found here:
http://api.jquery.com/jQuery.ajax/
Consider using a library that provides real time functionality such as SignalR, here is a link to the libraries site:
http://signalr.net/
Now for the personal opinions; Of all 3 options, the 3rd will provide you with the most "elegant" solution.
The 1st option will require you to use asp.net AJAX controls, which produce ugly HTML and can be a pig to work with. Also, timers on the client will be created which remove the true "real-time" aspects.
The 2nd option will again put timers on the client, removing the true "real-time" aspects.
The 3rd option, will allow the server to be "aware" of connected clients, data shall be pushed to the clients, when available, via the use of "Hubs".
Whilst your'e at this learning curve crossroad, I would also recommend looking into some client side JavaScript design patterns to help structure your code on the clients. A great tool to use could be Knockout, found here:
http://knockoutjs.com/index.html
Here is a tutorial on how to use this with SignalR:
http://www.codeproject.com/Articles/322154/ASP-NET-MVC-SIngalR-and-Knockout-based-Real-time-U
The tutorial focuses on using ASP.NET MVC. I imagine this should be interchangeable with web forms, however, if the option is available to you I would recommend using MVC also.

Update an ASP.NET page with Duplex WCF Service Call Result

I am having a problem to design the best way for invoking a duplex WCF service from ASP.NET Application I have the following scenario:
1) I have a duplex WCF service with some operations
2) From an ASP.NET web application (which is my client) I make the default page implement the callback Interface and then call a method from the duplex service sending itself as the handler of the callback
3) When the callback returns on the default.aspx page I couldn't show the result on the page because the whole HttpContext is null so I can't access any control or Application[] or Session[] variables
Here is the code in the Default.aspx
[CallbackBehavior(UseSynchronizationContext = false)]
public partial class _Default : System.Web.UI.Page, VehicleTrackingService.IDuplexServiceCallback
{
public _Default()
{
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
try
{
DuplexService client = new DuplexServiceClient(new InstanceContext(new_Default()));
switch (DropDownList1.SelectedItem.Value)
{
case "0":
{
client.Method1(int.Parse(txt_name.Text));
break;
}
case "1":
{
lbl_res.Text = "Not Provided yet.";
break;
}
default:
{
lbl_res.Text = "Not Provided yet.";
break;
}
}
}
catch(Exception ex)
{
}
}));
}
public void DuplexCallbackFunction(string response)
{
// Wanna to show result (the response) from here ...
}
Any Help Please?
You are calling the WCF service from the ASP.Net page while the page is being processed on the server.
The problem with this is that the page is on the server for a very short time, purhaps less than a second. Then the page has been returned to the browser before the WCF service has responded.
As Lloyd mentioned the way to fix this is to call the web service from your browser using AJAX.
For one example of how to do this see http://www.codeproject.com/Articles/128478/Consuming-WCF-REST-Services-Using-jQuery-AJAX-Call
You have to keep in mind that your application consists of a browser client that is accessing the ASP.NET application as a server, and these two communicate via HTTP requests and responses. Your ASP.NET application will most likely have sent an HTTP response back to the browser before the WCF service sends a message back to the ASP.NET application.
I think Shiraz and Lloyd have made an excellent suggestion; try to call the WCF service directly from the browser, if possible. This answer suggests that it may be possible to perform duplex communication with a WCF service with JavaScript.
However, there may be a number of reasons why you can't do that, such as credentials, network firewall rules, or simply the fact that the ASP.NET application has the necessary data to make the call to the WCF service, and perhaps you don't want to expose that data to the browser.
In these cases, you can choose to implement complicated solutions that involve using JavaScript in the browser to poll the ASP.NET server for updates. There are a couple of ways to do this. There is "short polling" and "long polling". There is also a relatively new feature called WebSockets, but whether or not your server and your target browser supports WebSockets is another question.

Categories

Resources