I have looked all over for a solution to an issue. I have noticed that in my android app, every time I fire an event from <button Clicked="GPSToggle_Clicked">, for some reason it increments the number of times my methods get called. So after I compile and load this on my phone, I hit my "GPSToggle_Clicked" button, and then to stop hit that button again. On the first "stop", I'll get a single instance of the below output:
---------------------------------------------------------------Attempting string parsing
---------------------------------------------------------------Sending string to SubmitGeneratedGPX
---------------------------------------------------------------path: /storage/emulated/0/Download/GPX/2022-10-27-02-44-06.gpx
---------------------------------------------------------------GPX File creation success
---------------------------------------------------------------:RawBufferToJsonString: [{"Timestamp":"2022-10-27T18:43:52.849+00:00","Latitude":41.5263818,"Longitude":-81.6507923,"Altitude":153.29998779296875,"Accuracy":20.0,"VerticalAccuracy":1.7990270853042603,"Speed":null,"Course":null,"IsFromMockProvider":false,"AltitudeReferenceSystem":2},{"Timestamp":"2022-10-27T18:43:53.696+00:00","Latitude":41.5263819,"Longitude":-81.6507921,"Altitude":153.29998779296875,"Accuracy":20.0,"VerticalAccuracy":1.7697961330413818,"Speed":null,"Course":null,"IsFromMockProvider":false,"AltitudeReferenceSystem":2},{"Timestamp":"2022-10-27T18:43:54.526+00:00","Latitude":41.5263819,"Longitude":-81.6507921,"Altitude":153.29998779296875,"Accuracy":20.0,"VerticalAccuracy":1.7697961330413818,"Speed":null,"Course":null,"IsFromMockProvider":false,"AltitudeReferenceSystem":2},{"Timestamp":"2022-10-27T18:43:55.374+00:00","Latitude":41.5263819,"Longitude":-81.6507921,"Altitude":153.29998779296875,"Accuracy":20.0,"VerticalAccuracy":1.7697961330413818,"Speed":null,"Course":null,"IsFromMockProvider":false,"AltitudeReferenceSystem":2},{"Timestamp":"2022-10-27T18:43:56.21+00:00","Latitude":41.5263811,"Longitude":-81.650792,"Altitude":153.29998779296875,"Accuracy":20.0,"VerticalAccuracy":1.7160584926605225,"Speed":null,"Course":null,"IsFromMockProvider":false,"AltitudeReferenceSystem":2}]
Every subsequent time I hit start/stop on the app, I get the real-time data in the output multiplied by the number of times I've started/stopped since the last compiling.
the main app page button event thats fired:
private async void GPSToggle_Clicked(object sender, EventArgs e)
{
var LocationPermissionStatus = await Xamarin.Essentials.Permissions.RequestAsync<Xamarin.Essentials.Permissions.LocationAlways>();
var FileReadPermissionStatus = await Xamarin.Essentials.Permissions.RequestAsync<Xamarin.Essentials.Permissions.StorageRead>();
var FileWritePermissionStatus = await Xamarin.Essentials.Permissions.RequestAsync<Xamarin.Essentials.Permissions.StorageWrite>();
if(LocationPermissionStatus == Xamarin.Essentials.PermissionStatus.Denied)
{
// TODO
return;
}
// run if device is android
if(Device.RuntimePlatform == Device.Android)
{
if (!CrossGeolocator.Current.IsGeolocationAvailable || !CrossGeolocator.Current.IsGeolocationEnabled)
{
// gps is not enabled, throw alert
Console.WriteLine("---------------------------------------------------------------GPS is DISABLED");
await DisplayAlert("Error", "GPS is not enabled. You must enable GPS to use this feature", "Ok");
}
else
{
// set our IsTracking = true flag
if (!IsTracking)
{
// start background listening for GPS
await StartListening();
Console.WriteLine("---------------------------------------------------------------Listening: " + CrossGeolocator.Current.IsListening);
StartService();
Console.WriteLine("---------------------------------------------------------------Service initiated");
IsTracking = true;
Console.WriteLine("---------------------------------------------------------------Tracking initiated");
GPSToggle.Text = "Stop Tracking";
}
else
{
//
// verify that the submittal wasn't done in error, before stopping services and submitting data
bool DoneInError = await DisplayAlert("Finish?", "Are you sure you want to stop services and submit?", "No", "Yes");
if (!DoneInError)
{
await StopListening();
Console.WriteLine("---------------------------------------------------------------listening:" + CrossGeolocator.Current.IsListening);
IsTracking = false;
Console.WriteLine("---------------------------------------------------------------Tracking ceased");
// stop the gps service
StopService();
Console.WriteLine("---------------------------------------------------------------Service ceased");
// stop the background listening for gps
Console.WriteLine("---------------------------------------------------------------Attempt GPX parse from buffer obj");
GPSToggle.Text = "Start Tracking";
}
}
}
}
}
Specifically the line:
StartService();
Fires this method off within the same class, specifically the MessagingCenter.Send<>, which initiates my foreground service to handle logging the gps data into a buffer:
private void StartService()
{
var startServiceMessage = new StartServiceMessage();
MessagingCenter.Send(startServiceMessage, "ServiceStarted");
Preferences.Set("LocationServiceRunning", true);
StatusLabel.Text = "Location service has been started";
Console.WriteLine("---------------------------------------------------------------location service has been started. preferences saved");
}
and
StopService();
Fires this method off to stop the services and retrieve the gps buffer data from the foreground to the main thread:
private void StopService()
{
var stopServiceMessage = new StopServiceMessage();
MessagingCenter.Unsubscribe<App, List<Location>>(this, "GPXBufferData");
MessagingCenter.Subscribe<App, List<Location>>(this, "GPXBufferData", (sender, args) =>
{
RawGPXData = args;
Generate_CreateGPX_File(RawGPXData);
RawBufferToJsonString = GPXParse.GenerateJSON_GPXPoints(RawGPXData);
Console.WriteLine("---------------------------------------------------------------:RawBufferToJsonString: " + RawBufferToJsonString);
PromptForSubmission_GPXPoints_API();
});
Console.WriteLine("--------------------------------------------------------------------------");
MessagingCenter.Send(stopServiceMessage, "ServiceStopped");
Preferences.Set("LocationServiceRunning", false);
Console.WriteLine("---------------------------------------------------------------Location service stopped. preferences saved");
}
In the above snippet, this line is subscribed to in the GPSLocationService.cs file:
MessagingCenter.Send(stopServiceMessage, "ServiceStopped");
This is a portion of my GPSLocationService.cs file that is relevant to this:
public async Task Run(CancellationToken token)
{
int ObjCount = 0;
await Task.Run(async () => {
// if the task was stopped
// check the buffer for data, if data, send to GPXGenerator
MessagingCenter.Subscribe<StopServiceMessage>(this, "ServiceStopped",
message =>
{
if (GPSBufferObj != null)
{
Device.BeginInvokeOnMainThread(() =>
{
MessagingCenter.Unsubscribe<App, List<Location>>((App)Xamarin.Forms.Application.Current, "GPXBufferData");
MessagingCenter.Send<App, List<Location>>((App)Xamarin.Forms.Application.Current, "GPXBufferData", GPSBufferObj);
});
}
});
return;
}, token);
}
I believe I have tracked down where the issue is starting. In my StopService() method, I have the following line (just to keep track of where Im at in the buffer) and it is only sent to output once.
Console.WriteLine("--------------------------------------------------------------------------");
BUT if I place that same line within the pasted portion of my GPSLocationService.cs file, I will get the incremented output. I'm leaning towards the nested task being the issue, I wrote this based losely off of this example repro:
https://github.com/jfversluis/XFBackgroundLocationSample
You don't have MessagingCenter.Unsubscribe<StopServiceMessage> anywhere in your code. StopServiceMessage is what you are accumulating subscriptions to.
You need to make sure Unsubscribe is unsubscribing the instance that was previously subscribed to. It sounds to me like there are multiple instances of GPSLocationService. [In which case, this is no longer referring to the original instance. Unsubscribe won't do anything, unless you have the this that was originally Subscribed.]
If so, instead create an instance of GPSLocationService ONCE, and store it in a static variable. Re-use it. start/stop it, but don't discard it.
Alternatively, if you only want a message ONE TIME from each Subscribe, then Unsubscribe as soon as you receive each message:
MessagingCenter.Subscribe<StopServiceMessage>(this, "ServiceStopped",
message =>
{
MessagingCenter.Unsubscribe<StopServiceMessage>(this, "ServiceStopped");
... your code ...
});
Use this same pattern EVERYWHERE you have a Subscribe (unless you Subscribe ONLY ONE TIME at app start, as Jason suggested.)
I am working on a web interface which manage virtual machines on vsphere Esx 5.5. My program is developed with .net web forms (not MVC).
I followed jeffpaton posts (using VMware.Vim ) which helped me (Thanks to you, Jeff) https://communities.vmware.com/thread/434579.
But now i freeze on this subject. I do not know how to wait a task after cloning VM. My web site launch vsphere command to the Vsphere Esx with vmware.vim. I need to know when vpshere finished his work to launch an another instruction.
I try to use PropertyCollector but i do not know how to use it :
i red this post but without success :
Here is a part of my code with a try but i am blocked. i use jeffpaton functions.
using VMware.Vim;
...
VimClient client;
string serverUrl = "..."
client.Connect("https://" + serverUrl + "/sdk");
client.Login(userLogin, userPassword);
...
ManagedObjectReference cloneTask_MoRef = null;
//1 waiting the cloning task
cloneTask_MoRef = sourceVm.cloneVM_Task(sourceVm.Parent, "cloneName", mySpec);
if (cloneTask_MoRef == null) {
//error
}else
{
PropertyCollector pc = new PropertyCollector(client, cloneTask_MoRef);
PropertyFilterSpec[] pfs = null;
RetrieveOptions ro = new RetrieveOptions();
RetrieveResult rResult = new RetrieveResult();
//PropertySpec
//pc.CreateFilter(pfs, true);
//rResult = pc.RetrievePropertiesEx(pfs,ro);
//
//2 PowerOn the CloneVM
cloneVM = this.vimClientTools.getVirtualMachines(selectedDC, cloneName)[0];
//3 waiting the powerOn Task...
//What could i do to know if the task is over or in progress ? :-(
I need some help. if somebody has a suggestion beginning...
Thanks for all.
This is probably too late, but here goes.
VimClient has a WaitForTask method;
client.WaitForTask(cloneTask_MoRef);
Alternatively, you could get the task and view its progress;
var task = (Task) client.GetView(cloneTask_MoRef, null);
while (task.Info.State != TaskInfoState.success)
{
Thread.Sleep(5000);
task.UpdateViewData();
if (task.Info.State == TaskInfoState.error)
throw new Exception($"The clone failed: {task.Info.Error.LocalizedMessage}");
Console.WriteLine(task.Info.Progress);
}
I have been trying to write Background Task that would show raw push notification as toast. I got push notifications working when app is running.
This is my background task class:
public sealed class BackgroundNotificationsTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
RawNotification notification = (RawNotification)taskInstance.TriggerDetails;
string content = notification.Content;
Debug.WriteLine("Background raw notification obtained!");
//SendNotification(content);
}
private void SendNotification(string text)
{
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
XmlNodeList elements = toastXml.GetElementsByTagName("text");
foreach (IXmlNode node in elements)
{
node.InnerText = text;
}
ToastNotification notification = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(notification);
}
}
Then I Register In MainPage.xaml.cs
private void RegisterTasks()
{
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
var taskRegistered = false;
var exampleTaskName = "NotificationsBackground";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
if(!taskRegistered)
{
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "BackgroundTasks.NotificationsBackground";
builder.SetTrigger(new Windows.ApplicationModel.Background.PushNotificationTrigger());
try
{
BackgroundTaskRegistration task = builder.Register();
Debug.WriteLine("Background Task registered.");
}
catch (Exception e)
{
Debug.WriteLine("Background Task register exception: " + e.ToString());
}
}
}
Now in appxmanifest I have set 'Lock screen notifications' to Badge, then in Declarations I have added Background Task with properies Push notification selected and entry point set as BackgroundNotificationsTask.cs
![screen][2]
Am I doing something wron or is there something that I am missing?
EDIT:
Right now when i obtain push notification the app closes... anyone know why?
There are a couple of things you're doing wrong.
1) Put your BackgroundTask in a separate project
BackgroundTask projects should be Windows Runtime Components. Also make sure that your background task resides under an accessible namespace. Do not forget to reference the background task project from your app project.
2) Register the correct class
When registering your background task, always use the fully qualified class name and not the file name:
BackgroundTasks.BackgroundNotificationsTask
This is the entry point you'll have to use in the package manifest file and in your code (given that the task class is in the project explained under 1) and the namespace is called BackgroundTasks).
3) Call RequestAccessAsync()
Make sure you call this before registering any tasks:
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
Edit: There is a pretty good walkthrough on MSDN https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx
I have used GetGeoPositionAsync() in my app and it works fine in the code of another feature, however when using it in the feature I am currently implementing, it freezes the first time I try to call it, and works the second time. I call this function when navigating from another page. Here's the code:
private async Task GetLocation()
{
Geolocator myGeolocator = new Geolocator();
Geoposition myGeoposition = null;
try
{
myGeoposition = await myGeolocator.GetGeopositionAsync();
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x80004004)
{
MessageBox.Show("Unauthorized access.");
}
}
}
I tried browsing SO, but haven't found a working solution for this. Why does it work in some pieces of code, and in some it just doesn't. What is the cause of this behaviour?
Ok, so I found a solution:
try
{
IAsyncOperation<Geoposition> locationTask = null;
try
{
locationTask = myGeolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(3));
myGeoposition = await locationTask;
}
finally
{
if (locationTask != null)
{
if (locationTask.Status == AsyncStatus.Started)
locationTask.Cancel();
locationTask.Close();
}
}
}
This sounds like the position is cached! The first time you call the method it tries to get your position (this can take many seconds if you are inside a building), the second time it seems to use the cached position.
To explain the title.. Selenium RC keeps insisting that
A system shutdown has already been scheduled
and refusing to conduct automated tests because of this.. I can understand the logic here, I mean you're not going to do your homework if you thought the world would end with a nuclear holocaust...
However.. this is not the Cold War and when I inspect several basic things (such as using shutdown \a, completing a full restart) I find that this is actually not the case!
How can I convince selenium that the world is not going to end and that it should probably do the work I'm telling it to?
N.B. Here, selenium has "refused" to initialise any instance of IE, and will continue to hang until it times out, regardless of clicking Yes or No. I'm using NUnit, c#/.net4.0 to control the tests.
To fix this I replaced the default "runSeleniumTest" function with the below patched version as a user extension:
function runSeleniumTest() {
runOptions = new RemoteRunnerOptions();
var testAppWindow;
if (runOptions.isMultiWindowMode()) {
try{
testAppWindow = openSeparateApplicationWindow('Blank.html', true);
}
catch (e) {
window.onunload = function () { };
window.location.reload();
return;
}
} else if (sel$('selenium_myiframe') != null) {
var myiframe = sel$('selenium_myiframe');
if (myiframe) {
testAppWindow = myiframe.contentWindow;
}
}
else {
proxyInjectionMode = true;
testAppWindow = window;
}
selenium = Selenium.createForWindow(testAppWindow, proxyInjectionMode);
if (runOptions.getBaseUrl()) {
selenium.browserbot.baseUrl = runOptions.getBaseUrl();
}
if (!debugMode) {
debugMode = runOptions.isDebugMode();
}
if (proxyInjectionMode) {
LOG.logHook = logToRc;
selenium.browserbot._modifyWindow(testAppWindow);
}
else if (debugMode) {
LOG.logHook = logToRc;
}
window.selenium = selenium;
commandFactory = new CommandHandlerFactory();
commandFactory.registerAll(selenium);
currentTest = new RemoteRunner(commandFactory);
var doContinue = runOptions.getContinue();
if (doContinue != null) postResult = "OK";
currentTest.start();
}
I found that the "a system shutdown has already been scheduled" error occurred inside of "openSeparateApplicationWindow". I also found that refreshing the selenium test runner window after the error occurred would "restart" the test without the error. Therefore, I patched the "runSeleniumTest" with the following try catch statement so the test runner window reloads if there's an error in "openSeparateApplicationWindow":
try{
testAppWindow = openSeparateApplicationWindow('Blank.html', true);
}
catch (e) {
window.onunload = function () { };
window.location.reload();
return;
}
I also used my blog post for a more specific example of selenium user extensions
Selenium isn't doing anything in this case. That's the IE HTA agent (a built-in Windows process) that's preventing you from doing anything. Perhaps rebooting the machine will do the trick? It looks like you may just have a pending Windows update that's scheduled a future reboot.