I am working on a windows iot core application running on a rasberry pi3
i tried to create/fetch the device key from the azure iot hub using the methods below
public MainPage()
{
systemName = "RaspIot";
this.InitializeComponent();
/* Register for the unloaded event so we can clean up upon exit */
Unloaded += MainPage_Unloaded;
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddDeviceAsync().Wait();
}
private static async Task AddDeviceAsync()
{
Device device;
try
{
device = await registryManager.AddDeviceAsync(new Device(systemName));
}
catch (DeviceAlreadyExistsException)
{
device = await registryManager.GetDeviceAsync(systemName);
}
deviceKey = device.Authentication.SymmetricKey.PrimaryKey;
}
If the device with name "RaspIot" is already registered an exception is thrown.
This is working fine in a .net45 console application. but in the UWP application for the PI3 the exception is thrown (pops up in while debugging) but not captured by the catch). what should i do differently?
I can reproduce your issue. And when running the UWP app using your code, the UI hangs and is not responsive. So it is not a best practice in UWP app.
In the UWP app, you can directly use AddDeviceAsync() without Wait(). It will execute normal and can catch the exception.
But in the console app, the app will exit without getting the task completion if you remove Wait() operator. So they are different.
For calling asynchronous APIs in UWP you can reference this document.
Update:
And it is not recommended register a device in the MainPage function since it will always be executed every time the app is started.
Related
I am working on an MQTTnet application for mobile/wearable devices. I've tested my code in both a standard C# Console application and .Net Core application, both work as expected. The issue I am having is when I port the code to Xamarin Forms, for running on a Galaxy Watch. The app will run for a few seconds, but then it will crash. I believe it could be from assigning the Label text too often?
I have an MQTT publisher device pumping out a simple position value at a 10ms interval. Where my other apps will just keep chugging along, the app in Xamarin will lock and then eventually crash. If it comment out the Label.Text assignment, the app keeps running without a crash.
Here is my Xamarin code, is there a better way to handle the assignment?
// Event Handler to the ApplicationMessageRecevied event
client.ApplicationMessageReceived += (s, e) =>
{
StatusLabel.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
};
I found that using the following to assign the label works well. My publisher is sending messages at 2ms intervals, and the watch is stable!
Device.BeginInvokeOnMainThread(() => {
PositionData.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
});
I am currently working on a windows service application that already consuming SignalR service. My new requirement is to start a desktop application when windows service receives a notification from SignalR.
While I am google on how to start a desktop application using windows service, I found this code base and I am currently using it.
As it explains, when I called the bellow method
ProcessExtensions.StartProcessAsCurrentUser(string path);
in the windows service's OnStart method I was able to start the desktop application.
I also have SignalR client in this windows service (Bellow code).
public class NotificationHub
{
public static void ConsumeNotification()
{
try
{
var hubConnection = new HubConnection(url);
IHubProxy notificationHubHubProxy = hubConnection.CreateHubProxy("WSMassageHub");
hubConnection.Start().Wait();
notificationHubHubProxy.On<WSMessage>("SendMessage", (message) => {
// try to start from here
// but it gives error
ProcessExtensions.StartProcessAsCurrentUser(#"D:\Application\Application.exe");
});
}
catch (Exception ex)
{
logger.Error("Message: " + ex.Message + " | Stack Trace: " + ex.StackTrace);
}
}
}
Then I try to start the desktop application from windows service when windows service gets the message to SignalR client.
protected override async void OnStart(string[] args)
{
NotificationHub.ConsumeNotification();
}
Once SignalR client gets a message, the application failed and error log gets this error message.
StartProcessAsCurrentUser: CreateProcessAsUser failed. Error Code -2
According to System Error Codes, it says that The system cannot find the file specified.
Also, I suspect that this will explain the issue in here. But I don't understand that which component needs to implement to start the desktop application, once SignalR client receives the notification. So, can someone please give me help hand to overcome this issue.
Thanks in advance.
I have created a BackgroundTask to run a WebService, however if i run my solution with debugger attached, everything works fine, slowly, but fine. But when i hit start in the appmanager (webinterface) it always says "failed to start package [MYPACKAGEID]". So what am i missing?
Here is the complete project: https://github.com/naice/HomeAutomation.git
public sealed class StartupTask : IBackgroundTask
{
internal static BackgroundTaskDeferral Deferral = null;
public async void Run(IBackgroundTaskInstance taskInstance)
{
//
// TODO: Insert code to perform background work
//
// If you start any asynchronous methods here, prevent the task
// from closing prematurely by using BackgroundTaskDeferral as
// described in http://aka.ms/backgroundtaskdeferral
//
Deferral = taskInstance.GetDeferral();
await ThreadPool.RunAsync(async workItem => {
RestWebServer restWebServer = new RestWebServer(80);
try
{
// initialize webserver
restWebServer.RegisterController<Controller.Home.Home>();
restWebServer.RegisterController<Controller.PhilipsHUE.Main>();
await restWebServer.StartServerAsync();
}
catch (Exception ex)
{
Log.e(ex);
restWebServer.StopServer();
Deferral.Complete();
}
}, WorkItemPriority.High);
}
}
The point is that there is no problem with the code or even the manifest, it seems that it's just not meant to run while the device is in "headed" mode, you need to set it as a satrtup headless app and then restart the device.
Edit: All these problems are gone with the latest version 10.0.14279.1000 and now the GUI finally works as it should.
I have been struggling with this to and have had great success with this method that might help someone. All is done in Power Shell
Put the device into headless mode, in some way I don´t think this is mandatory but I have not succeeded without it.
Edit: This is not the case any more, it works as it should now.
https://ms-iot.github.io/content/en-US/win10/HeadlessMode.htm
Start the app in headless mode and add it to the startup app list
To see what apps are in the startup list type
IotStartup startup
To add a headless app type in command
IotStartup add headless [Task1]
To add a headless app type in command
IotStartup startup headless [Task1]
To find the app name you can use the command
IotStartup list
To see that your app are in startup list type
IotStartup startup
Then reboot your device!
I have also had some problems related to removing apps from startup and then try to debug them via Visual Studio and in some cases the only solution were to flash the SD card with a new image.
For a complete list of available commands
https://ms-iot.github.io/content/en-US/win10/tools/CommandLineUtils.htm
I am using the following code to check for network access in the start of my application
public async void CheckNetwork()
{
if (!NetworkAvailabilty.Instance.IsNetworkAvailable)
{
MessageDialog Message = new MessageDialog("Network access not available.", "Network Error");
Message.Commands.Add(new UICommand("Close"));
await Message.ShowAsync();
Application.Current.Exit();
}
}
This works as expected in Windows 10 desktop. But when I am running the app in my Phone, it fails to close the app. What could be the reason for this and how to force close my app ?
As a design principle, you are not supposed to manually close an app. Please refer to this link (adressed to WP8 developers, but is still valid).
But, if you are working on a test app for yourself, you can throw an exception which is the only way possible to close the app.
throw new Exception();
Please don't do that if you aim to publish your app on the market :
An unhandled exception in your app consumes resources unnecessarily both on the user’s phone and on the Windows Phone servers.
The phone generates and uploads crash dumps for unhandled exceptions to help you find and fix bugs in your code. Crashing your app to close it wastes the user’s battery power and network bandwidth.
try Application.Current.Terminate() instead of Exit()
Try execute ApplicationView.GetForCurrentView().TryConsolidateAsync().
I am successfully able to call the Web Api deployed on below link from mobile app or console app.
https://dposapi.azurewebsites.net/DPosApi/v1/Configurations/GetAll
Problem is that when i put this call in BackgroundTask in a RunTime Component project and triggers the background task from mobile app than execution hangs on the line of code where i am calling the Web Api. Sample is available on below link.
https://github.com/imranshabbir/Sample
What could be the problem?
Your run method should be async, like this: (note the await before FillProducts() )
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral deferal = taskInstance.GetDeferral();
// do your task here
await FillProducts();
deferal.Complete();
}
Btw. are you sure that the
"execution hangs on the line of code where i am calling the Web Api"
?
In your current code the problem is that the background task is finished before you get the results (without the await the execution hits the deferal.Complete(); line earlier). So in that case you just don't see the results, but that should not be a hang.
But anyway... async/await is the answer.