async on page load in xamarin.forms - c#

I'm currently developping a small application based on a Master Detail template. One of my Pages requires some data to be loaded immediatly, and I dont know how to do this. In every example, data is loaded once user press a button.
Here is my current code :
string test = async (sender, e) => {
Task<string> json = GetRandomRelations ();
return await json;
};
And my method
public async Task<string> GetRandomRelations () {
var client = new System.Net.Http.HttpClient ();
client.BaseAddress = new Uri("http://127.0.0.1/loltools/web/app_dev.php/api/relation/");
string response = await client.GetStringAsync("random/20");
return response;
}
I'm currently just trying to get the json response, but I cannot even manage to do that... My main problem is that I cannot convert the lambda expression to string...
Thanks for your help !

One of my Pages requires some data to be loaded immediatly, and I dont know how to do this.
Think about this for a bit. What you're really asking is how to reconcile two opposing requirements:
The page must show some data immediately. The UI must be responsive. The data must be available synchronously to display.
The data is retrieved asynchronously. It is not available immediately. It will take some (unknown) amount of time to even get the data to display.
So, obviously, there's no direct solution. Instead, you have to satisfy the both of the core requirements ("The UI must be responsive" and "The data is retrieved asynchronously") in a different way. One common approach is to (immediately and synchronously) display a "Loading..." view of the data - a spinner or whatnot. Then, update the display when the data arrives.

I'm not absolutely sure what you are trying to do but what's wrong with simply:
string test = await GetRandomRelations ();

Related

WebView2 CallDevToolsProtocolMethodAsync issue with Fetch.continueRequest

I'm using WebView2 in a .net 5 WPF app and have been playing with the devtools protocol as a means of intercepting specific requests for assets. In looking at the Chrome dev docs (https://chromedevtools.github.io/devtools-protocol/), it's possible to intercept requests and then decide whether to continue them, cancel them or satisfy them yourself.
I've been able to successfully intercept the first web request (Eg. https:// www.somedomain.tld), but I've not been able to successfully continue the request (which would presumably trigger any other asset requests made as a result of the parsed html response).
After WebView initialization, I do the following (which works):
// Intercept requests
var receiver = webView.CoreWebView2.GetDevToolsProtocolEventReceiver("Fetch.requestPaused");
receiver.DevToolsProtocolEventReceived += FetchRequestPaused;
await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Fetch.enable", "{}");
This is my event handler - which doesn't do what I'm expecting it to (although it doesn't deadlock now at least):
private void FetchRequestPaused(object sender, Microsoft.Web.WebView2.Core.CoreWebView2DevToolsProtocolEventReceivedEventArgs e)
{
var doc = JsonDocument.Parse(e.ParameterObjectAsJson);
var id = doc.RootElement.GetProperty("requestId");
var payload = $"{{\"requestId\":\"{id}.0\"}}";
// We can't do this as an async call as it will try to post to the main thread, which is
// busy waiting in this event handler, so we deadlock
//_ = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Fetch.continueRequest", payload);
// Exception: Value does not fall within the expected range.
// var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Fetch.continueRequest", payload).ConfigureAwait(false);
// PROBLEM: This invokes the call on the UI thread OK...
Application.Current.Dispatcher.Invoke(new Action(() =>
{
// ...but it doesn't actually do anything
webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Fetch.continueRequest", payload);
}));
}
Not only does the requested page not finish loading, but the browser is left in an unusual state and so right-clicking on the control and selecting "Refresh" will crash - yielding a COMException:
System.Runtime.InteropServices.COMException: 'The group or resource is not in the correct state to perform the requested operation. (0x8007139F)'
Can anyone see what I'm doing wrong here or am missing??
Thanks!
Additional information
In swapping out the events for the deprecated Network.setRequestInterception / Network.continueInterceptedRequest equivalents, I'm seeing the same behaviour - which at least tells us that it's either a problem with my calling code (most likely) or a bug in WebView2 (possible) rather than Chromium.
Any thoughts?
After some more digging, I realised there were two problems. The first is that my installed version of Edge was slightly behind. The second was that my Action delegate was synchronous. The call should read:
// Somebody forgot some 'async' keywords..!
Application.Current.Dispatcher.Invoke(new Action(async () =>
{
var x = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Fetch.continueRequest", payload);
}));

Processing API data as it comes in .NET

Is it possible to read API data as it comes , I wrote the below Csharp code in my controller but sometimes the data takes more than 2 minutes and I was wondering if it was possible to load the data in my website as they come instead of waiting for it. Below is my current code:
private static async Task<List<Model>> GetFlightData()
{
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
var content = await client.GetStringAsync(URL);
var result = JsonConvert.DeserializeObject<List<Model>>(content);
return result;
}
}
The fastest way is to save the data statically and initialize it on start up,
the problem with this solution is that IIS may restart you website when there's no traffic and the data will be lost (and will cause the next visitor to wait a whole 2 minutes).
The best suggestion I have is to save it to redis/other cache of your chosing and then just pull it from there.

How can I use correctly the activity indicator on Xamarin.forms for Android?

I'm using this plugin for showing that the app is busy, but on Android the animation is always stuck.
For example I use it in this code:
private async Task SelectWorkOrderItemAsync(WorkOrderLista WoLista) {
if (WoLista == null) return;
// show the loading
Acr.UserDialogs.UserDialogs.Instance.ShowLoading("Loading..");
// get datas from DB
WorkOrderDettaglio WoDett = await _WorkOrderService.GetDettaglioWorkOrder(WoLista.Guid_servizio);
// this code opens another page with the datas extracted above
await NavigationService.NavigateToAsync<DettaglioWoViewModel>(WoDett, Costanti.TipoPush.Normale, WoDett.NumWoAnno);
// hide the loading
Acr.UserDialogs.UserDialogs.Instance.HideLoading();
}
This is the result:
as you can see, the loading indicator after some seconds become freezed.
This behaviors is the same if I use the default ActivityIndicator.
On IOS all works fine.
How can I correctly use it?
I don't have an Android device/simulator to test at the moment and can't reproduce on UWP, but your service call is being executed asynchronously on the main thread, your ActivityIndicator should not be blocked if you execute your service call in a worker thread.
// get datas from DB
WorkOrderDettaglio WoDett = null;
await Task.Run(async () => WoDett = await _WorkOrderService.GetDettaglioWorkOrder(WoLista.Guid_servizio));
The activity indicator must be binded (isVisibleProperty and isRunningProperty) to a bool property on your ViewModel and your ViewModel must implement
INotifyPropertyChanged
Here is a greate explanation on how to achieve that.
If an overlay is needed in this answer you can find out how to achieve that.

How to call a script with SignalR when item created to DB

I'm newbie with SignalR and want to learn so much. i already read beginner documents. But in this case i've stucked. what i want to do is when a user got new message i want to fire a script, like alert or showing div like "you have new mail" for notify the recieved user. And my question is how can i do that ? is there anyone know how to achieve this ? or good "step-by-step" document? i really want to work with SignalR.
ps: i'm using Visual Studio 2012 and MsSQL server
edit: i forgot to write, notification must be fired when message created to DB
Thank you
In your Scripts use the following, naturally this is not all the code, but enough based off tutorials to get you going. Your userId will be generated server side, and somehow your script can get it off an element of the page, or whatever method you want. It runs when the connection is started and then every 10 seconds. Pinging our server side method of CheckMessage() .
This js would need refactoring but should give you the general idea.
...
var messageHub = $.connection.messageHub;
var userId = 4;
$.connection.hub.start().done(function () {
StartCheck();
}
//Runs every 10 seconds..
function StartCheck()
{
setInterval(messageHub.server.checkMessage(userId,$.connection.hub.id), 10000);
}
This method takes in a userId, assuming your db is set up that way, and grabs them all from your database; naturally the method used is probably not appropriate for your system, however change it as you need to. It also checks if the user has any messages, and if so sends down another message to our SignalR scripts.
public void CheckMessage(int userId,int connectionId)
{
var user = userRepo.RetrieveAllUsers.FirstOrDefault(u=>u.id == userId);
if(user.HasMessages)
{
Clients.Group(connectionId).DisplayMailPopUp();
}
}
Finally this message, upon being called would run your code to do the 'You have Mail alert' - be it a popup, a div being faded in or whatever.
...
messageHub.client.displayMailPopUp = function () {
alert("You have Mail!");
};
...
Hopefully this helps - I recommend the following links for reading up and building your first SignalR app:
http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-getting-started-with-signalr-20-and-mvc-5
And a smaller sample: http://code.msdn.microsoft.com/SignalR-Getting-Started-b9d18aa9

C# How to process several web requests at once

I have been reading a lot about ThreadPools, Tasks, and Threads. After awhile I got pretty confused with the whole thing. Lots of people saying negative/positive things about each... Maybe someone can help me find a solution for my problem. I created a simple diagram here to get my point across better.
Basically on the left is a list of 5 strings (URL's) that need to be processed. In the center is just my idea of a handler that has 2 events to track progress. Inside that handler it takes all 5 URL's creates separate tasks for them, shown in blue. Once each one complete I want each one to return the webpage results to the handler. When they have all returned a value I want the OnComplete to be called and all this information passed back to the main thread.
Hopefully you can understand what I am trying to do. Thanks in advance for anyone who would like to help!
Update
I have taken your suggestions and put them to use. But I still have a few questions. Here is the code I have built, mind it is not build proof, just a concept to see if I'm going in the right direction. Please read the comments, I had included my questions on how to proceed in there. Thank you for all who took interest in my question so far.
public List<String> ProcessList (string[] URLs)
{
List<string> data = new List<string>();
for(int i = 0; i < URLs.Length - 1; i++)
{
//not sure how to do this now??
//I want only 10 HttpWebRequest running at once.
//Also I want this method to block until all the URL data has been returned.
}
return data;
}
private async Task<string> GetURLData(string URL)
{
//First setup out web client
HttpWebRequest Request = GetWebRequest(URL);
//
//Check if the client holds a value. (There were no errors)
if (Request != null)
{
//GetCouponsAsync will return to the calling function and resumes
//here when GetResponse is complete.
WebResponse Response = await Request.GetResponseAsync();
//
//Setup our Stream to read the reply
Stream ResponseStream = Response.GetResponseStream();
//return the reply string here...
}
}
As #fendorio and #ps2goat pointed out async await is perfect for your scenario. Here is another msdn article
http://msdn.microsoft.com/en-us/library/hh300224.aspx
It seems to me that you are trying to replicate a webserver within a webserver.
Each web request starts its own thread in a webserver. As these requests can originate from anywhere that has access to the server, nothing but the server itself has access or the ability to manage them (in a clean way).
If you would like to handle requests and keep track of them like I believe you are asking, AJAX requests would be the best way to do this. This way you can leave the server to manage the threads and requests as it does best, but you can manage their progress and monitor them via JSON return results.
Look into jQuery.ajax for some ideas on how to do this.
To achieve the above mentioned functionality in a simple way, I would prefer calling a BackgroundWorker for each of the tasks. You can keep track of the progress plus you get a notification upon task completion.
Another reason to choose this is that the mentioned tasks look like a back-end job and not tightly coupled with the UI.
Here's a MSDN link and this is the link for a cool tutorial.

Categories

Resources