WP7 Emulator VS Device. download performance - windows-phone-7

I developed WP7 application using the emulator. Everything was great. To communicate with the server I used WebClient and RestClient. But to test the application on a real device - I threw a shock.
1)
private void LoadData()
{
var webClient = new WebClient();
webClient.DownloadStringCompleted += DownloadStringCompleted;
webClient.DownloadStringAsync(new Uri(Constants.Url1));
//Point_1
}
private void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//Point_2
}
On emulator between Point_1 and Point_2 0.8-1.2 seconds.
On real device (HTC Radar WP7.8) between Point_1 and Point_2 15-20 seconds.
2)
var request = new RestRequest(url) {Method = Method.POST};
//Point_3
RestClient.ExecuteAsync(request, response =>
{
//Point_4
}
On emulator between Point_3 and Point_4 0.3-0.5 seconds.
On real device (HTC Radar WP7.8) between Point_3 and Point_4 18-22 seconds.
My computer and phone in same wi-fi network.
I have three questions:
First: It's normal?
Second: Why it's happening?
Third: How can I solved it?

There are many factors however its worth remembering that emulator performance is usually lot better than device and that you should try on device.
Having said that, you should consider alternate models of data display,
e.g. make a call and then populating data as it arrives in chunks using something like ObservableCollection.
You could also implement downloading the data using background task and having it already available.
In the end, it depends on what you can and cannot do.

Like Hermit says: "There are many factors however its worth remembering that emulator performance is usually lot better than device and that you should try on device."
My solution is - do not use debug mode, when you test network performance on real device. Just create XAP file and load it on device.

Related

It is possible background works for every 1 minutes in ios?

Hello firstly I am so sorry about my bad english level.
I have an application.
Basically my application works for every 1 minutes use get method for getting some json data from server.
It is possible in android side and i created with foreground service.
But for xamarin.ios side how i can create?
actually my question is it is possible for in ios?
Before doing that , you can have a research with backgrond tasks in iOS .
The biggest change in iOS 7 with regard to background tasks is not how the tasks are implemented, but when they run.
Recall that pre-iOS 7, a task running in the background had 600 seconds to complete. One reason for this limit is that a task running in the background would keep the device awake for the duration of the task:
iOS 7 background processing is optimized for longer battery life. In iOS 7, backgrounding becomes opportunistic: instead of keeping the device awake, tasks respect when the device goes to sleep, and instead do their processing in chunks when the device wakes up to handle phone calls, notifications, incoming emails, and other common interruptions. The following diagram provides insight into how a task might be broken up:
Because the task run time is not longer continuous, tasks that perform network transfers must be handled differently in iOS 7. Developers are encouraged to use the NSURlSession API to handle network transfers. The next section is an overview of background transfers.
If you can keep the device not be killed , you can have a try with using System.Threading.Timer class to use Timer to implement what your want:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
private static Timer timer;
static void Main(string[] args)
{
var timerState = new TimerState { Counter = 0 };
timer = new Timer(
callback: new TimerCallback(TimerTask),
state: timerState,
dueTime: 1000,
period: 2000);
while (timerState.Counter <= 10)
{
Task.Delay(1000).Wait();
}
timer.Dispose();
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
}
private static void TimerTask(object timerState)
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
var state = timerState as TimerState;
Interlocked.Increment(ref state.Counter);
}
class TimerState
{
public int Counter;
}
}
In addition , the first doc share the Background Transfers notes .The backbone of background transfers in iOS 7 is the new NSURLSession API.

Geolocation.GetLastKnownLocationAsync() sometimes returns null

This is on iOS 12.1.4 on an iPhone 6s. Usually Geolocation.GetLastKnownLocationAsync() works but sometimes it doesn't. It's the exact same code but if I sit here and press my "get latitude and longitude" button over and over eventually Geolocation.GetLastKnownLocationAsync() spits out a null.
Do you know why this happens and how I might handle it? Perhaps put it in a loop that tries ten times, waiting a second between each try?
var location = await Essentials.Geolocation.GetLastKnownLocationAsync(); // works most of the time but sometimes it doesn't work.
This is my proposed work around:
Essentials.Location location = null;
for(var i = 0; i < 10; i++)
{
location = await Essentials.Geolocation.GetLastKnownLocationAsync();
if(location == null)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
First, it is really bad practice to use Thread.Sleep (unless you are not on the main/UI loop) as you are hanging the run loop, if you really need a delay, use await Task.Delay(.... Also CLLocationManager on iOS is running on the main loop and if you are blocking it, the message pump is hung and the location manager manager can not report back to the app.
"Spamming" CLLocationManager.Location (which Essentials is using on iOS) can (and will) result in null returns due to OS rate limiting updates (mainly a battery conservation measure) and if the OS is powering up the GPS radio to update its location, this method will timeout on from the OS, thus report nil back to GetLastKnownLocationAsync and thus you get a return of null.
CLLocationManager.Location on iOS is meant for a quick low-power return from the OS to app as is updated upon app launch, device reboot, etc... not every time you call it.
You can get the last known location of the device by calling the GetLastKnownLocationAsync method. This is often faster then doing a full query, but can be less accurate.
Otherwise you should be using GetLocationAsync in order to do a full GPS power up to obtain an updated accurate location.
To query the current device's location coordinates, the GetLocationAsync can be used. It is best to pass in a full GeolocationRequest and CancellationToken since it may take some time to get the device's location.
Typically I recommend using GetLastKnownLocationAsync as a quick way to get the general area of the user knowing that this might also return null. Then proceed to do a GetLocationAsync (passing both a GeolocationRequest and CancellationToken instance) in the background and update the app accordingly upon the more accurate and recent position.
re: https://learn.microsoft.com/en-us/xamarin/essentials/geolocation?tabs=ios

Network throttling with chrome and selenium

Google Chrome 38 introduced the new "Device Mode & Mobile Emulation" functionality in devtools. In addition to choosing a device for emulation, it is also possible to emulate different network conditions:
Optimizing your site's performance under varying network conditions is
a key aspect of developing for a mobile audience.
Device mode's network conditioning allows you to test your site on a
variety of network connections, including Edge, 3G, and even offline.
Select a connection from the preset dropdown to apply network
throttling and latency manipulation.
For example, we can set it to be like in good old days - GPRS 50 Kbps:
Now we have a good use case for it - we have an internal application for network speed testing. And this new emulation functionality is very helpful for manual testing. But, we'd like to automate it.
Question is:
Is it possible to start chrome via selenium with specified network conditions? Is it something that can be controlled through chrome preferences or command-line arguments?
There are certainly multiple options to simulate slow internet connection, but the question is specifically about chrome+selenium.
The API to control network emulation were added to ChromeDriver. And should be available for quite a while now. According to comment in the linked issue you should use version at least 2.26 because of some bugfix.
According to Selenium changelog bindings are available for these languages:
JavaScript as of version 3.4.0 (commit)
Python as of version 3.5.0 (commit)
Ruby as of version 3.11.0 (commit)
C# as of version 4 (commit)
If you need these binding in other languages you should probably open issue/contribute implementation similar to one of the above.
Example usage from Python is below:
driver.set_network_conditions(
offline=False,
latency=5, # additional latency (ms)
download_throughput=500 * 1024, # maximal throughput
upload_throughput=500 * 1024) # maximal throughput
No, it is not possible to control Network Connectivity Emulation through Chrome preferences or command-line arguments. Network Connectivity Emulation is part of the build-in Chrome debugger. One way way in solving this is to control the debugger. This can be done via an extension or by directly controlling the debugger, see explanation. However, this will not work with WebDriver. The reason for this is that there can only be one "debug" session and WebDriver is already using it, see explanation. Since there is no public interface, there is also no way to control it via WebDriver.
For Device Mode & Mobile Emulation which is also part of the build-in debugger, there is a public interface (details), and thus can be controlled. This can be done through WebDriver Capabilities. Two options 1) Specify a device name 2) Enter your own parameters (limited).
You can use this method to run your test case in specified network conditions
protected void networkThrotting() throws IOException {
Map map = new HashMap();
map.put("offline", false);
map.put("latency", 5);
map.put("download_throughput", 500);
map.put("upload_throughput", 1024);
CommandExecutor executor = ((ChromeDriver)driver).getCommandExecutor();
Response response = executor.execute(
new Command(((ChromeDriver)driver).getSessionId(), "setNetworkConditions", ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map)))
);
}
Indeed C# Selenium latest (3.11) has NetworkConditions added. Now you can use it like this:
var driver = new ChromeDriver(pathToDriver);
driver.NetworkConditions = new ChromeNetworkConditions()
{ DownloadThroughput = 5000, UploadThroughput = 5000, Latency = TimeSpan.FromMilliseconds(5) };
The problem is it's not yet usable because of the bug
https://github.com/SeleniumHQ/selenium/issues/5693
So .Net guys will have to wait until 3.12 Selenium Release.
While this is a very welcome and useful bit of functionality, for serious testing I think the conventional methods of network simulation are still the way to go.
I am aware of 2 solutions in addition to those already linked - the Charles web proxy (very useful tool - commercial) and implementing your own recipe using Linux Traffic Control (e.g. see chapter 6 of LAMPe2e).
By interfering with the network connections rather than the browser, you then get a proper measure of the impact independently of the browser in use.
Why do you just want to use the Chrome functionality?
Let's consider two different approaches,
one where we can throttle the entire network and one where we can specify which network requests to throttle specifically.
Approach 1: throttle the entire network
const { Builder } = require("selenium-webdriver")
async function throttleNetwork() {
let driver = await new Builder().forBrowser("chrome").build();
await driver.setNetworkConditions({
offline: false,
latency: 5000, // Additional latency (ms).
download_throughput: 50 * 1024, // Maximal aggregated download throughput.
upload_throughput: 50 * 1024, // Maximal aggregated upload throughput.
});
driver.get("http://www.google.com/");
}
thanks to Yaroslav for pointing out the commit.
This has a downside where we can't specify a specific network request to throttle and the rest to go unthrottled.
Let's fix this downside in our next approach.
Approach 2: throttle a specific network request
Here we'd be using an npm package from requestly called Requestly for Selenium.
We need to create a rule first in their client application and get the link by creating a shared list.
For example, let's throttle network request to google.com
require("chromedriver");
const { Builder } = require("selenium-webdriver");
const chrome = require("selenium-webdriver/chrome");
const {
getRequestlyExtension,
importRequestlySharedList,
} = require("#requestly/selenium");
const sharedListUrl = "YOUR_SHARED_LIST_LINK_HERE" // For example, use "https://app.requestly.io/rules/#sharedList/1631611216670-delay"
async function throttleGoogle() {
const options = new chrome.Options().addExtensions(
getRequestlyExtension("chrome") // This installs requestly chrome extension in your testing instance
);
const driver = new Builder()
.forBrowser("chrome")
.setChromeOptions(options)
.build();
await importRequestlySharedList(driver, sharedListUrl); // Here we import the shared list we created some time back
driver.get("http://www.google.com/");
}
This was a high-level overview of how we can overcome the downsides of the selenium-only approach. I've written a blog on the same where I go into depth on how to create a rule, shared list, and so on. You can read it here.
The below issue has now been fixed in this commit
For anyone like me in the C# world wondering why the upload/download throughput does not work as expected, it seems the tooltips for these properties are mislabelled. The tooltip states the data rate is measured in kb/s but in my own experience it is actually bytes per second so if you want to use a more familiar measurement like Mbps you will have to multiply by 125,000:
int latencyInMilliseconds = 20;
long downloadLimitMbps = 20;
long uploadLimitMbps = 5;
_driver.NetworkConditions = new ChromeNetworkConditions()
{
Latency = new TimeSpan(0, 0, 0, 0, latencyInMilliseconds),
DownloadThroughput = downloadLimitMbps * 125000, // Mbps to bytes per second
UploadThroughput = uploadLimitMbps * 125000, // Mbps to bytes per second
IsOffline = false,
};
Using these settings and looking at network traffic while my tests are running I can see they result in exactly 20Mbps down and 5Mbps up.
It looks like it's coming soon to Selenium (C#). The commit was on 01/28/2018:
https://github.com/SeleniumHQ/selenium/blob/ef156067a583fe84b66ec338d969aeff6504595d/dotnet/src/webdriver/Chrome/ChromeNetworkConditions.cs
I know this is an old question, but I recently had to solve for this problem and this page came up at the top of my Google search. Here are the main bits from how I did it in C#. Hope this helps someone in the future.
var networkConditions = new ChromeNetworkConditions();
networkConditions.Latency = new TimeSpan(150);
networkConditions.IsOffline = false;
networkConditions.DownloadThroughput = 120 * 1024;
networkConditions.UploadThroughput = 150 * 1024;
Driver.NetworkConditions = networkConditions;
Inspired by the answer from TridentTrue, here is an updated version for Selenium 4.0.0 in C#. If anyone knows how to use it for alpha7 and upwards without beeing version specific feel free to update this. :)
public void LimitNetwork(int latencyInMilliseconds, long downloadLimitMbps, long uploadLimitMbps)
{
IDevTools devTools = driver as IDevTools;
session = devTools.CreateDevToolsSession();
session.Network.Enable(new EnableCommandSettings());
EmulateNetworkConditionsCommandSettings command = new EmulateNetworkConditionsCommandSettings();
command.Latency = latencyInMilliseconds;
command.DownloadThroughput = downloadLimitMbps * 125000; // Mbps to bytes per second
command.UploadThroughput = uploadLimitMbps * 125000; // Mbps to bytes per second
command.Offline = false;
session.Network.EmulateNetworkConditions(command);
}
Update: After I had implemented this for my own, I found a really good article to get an overview in Selenium 4.0, also in Emulating network conditions.
Update 2: My issue was that I forgot to add the Network.Enable command, so don't forget to call it before you do the other stuff.
I have updated the code. :)

Flex - Dispatching Remote Object Result Event

I'm developing a flex application, that brings data from server using "RemoteObject" . I am using AMFPHP for server side remoting. The problem is when i call a specific method using AMFPHP's service browser , result data comes up in 9-10 seconds. But when i call the same method from my flex application , it takes 20-40 seconds !!!
the code which is sending a remote object request to my server is
remoteObject.destination = "decoyDestination";
remoteObject.source = "PHP/manager1";
remoteObject.endpoint = "http://insight2.ultralysis.com/0Amfphp/Amfphp/";
remoteObject.addEventListener(FaultEvent.FAULT,handleFault);
remoteObject.addEventListener(ResultEvent.RESULT,handleResult);
var params:Object = new Object();
params.action = "default";
params.ValueVolume = 1;
timer.start();
remoteObject.init(params);
and my handle result function is
private function handleResult (event:ResultEvent):void
{
timer.stop();
CursorManager.removeAllCursors();
Alert.show("result found at: "+timer.currentCount/60+" seconds");
}
The average timing is 30 seconds at least. As much as i know about remoting with amfphp it should work more and more faster. Am i missing something ?
*Note: using FB's built in Network Monitor i can see that a request is being sent. But the response time and elapsed time is always blank. Event after the response is received
Any kind of help will be appreciated
Thanks in advance
A few things I would like you to try,
Having the network monitor turned on, will cause the performance hit - so, turn it off,
Service browser is obviously not running in debug mode, if you export release build your project and try to call these services, you should be able to see the response much quicker 9-10 seconds as you would expect, (running the app in debug mode always takes more time, looking at the response time,i'm thinking that you are getting a lot of data from the server which obviously takes time when in Debug mode)

In WP7, data is not saved immediately after writing to IsolatedStorage

I encountered this problem while polishing my WP7 application.
Though I follow Microsoft's guidelines to store game state when it's being deactivated, I'd also like to save some data in runtime.
The reason for this is that when the battery is removed from device, no deactivation / closing callbacks are triggered.
The problem with this comes when the user walks through the game and accidentally removes the battery from her device - all game progress is lost.
That's why I do save game state at some intermediate checkpoints, but I have noticed that data is not stored immediately. This is my "save" function:
public void SaveAppModelToIsolatedStorage()
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(APPMODEL_DATAFILE,
FileMode.Create,
FileAccess.Write,
store))
{
var serializer = new XmlSerializer(typeof(AppModel));
try
{
serializer.Serialize(stream, AppModel);
}
catch (Exception ex)
{
Debug.WriteLine("Cant serialize AppModel:" + ex.Message);
}
}
}
After it's been called, if I remove the battery within a number of seconds (not sure how many but always less than 30), the application ends up with lost game progress. If I wait before removing battery, the data would be saved successfully. This behavior is observed on various WP7 phones.
I also tried serialization into a string buffer and then writing that string buffer to the file by calling stream.Write(), but the result is the same. Also, stream.Flush() doesn't seem to have an effect.
Is this behavior a platform feature?
Is it fine in terms of Microsoft certification for Marketplace apps?
Or is there a way to save data immediately?
Just call stream.Close when you need flush your data.
Also, try calling stream.Flush(true);
This may be interesting regarding performance of Isolated Storage : forums.create.msdn.com/forums/p/71708/71708.aspx

Resources