Background Task does not run in UWP - win-universal-app

I have a UWP application where I want to add background task support for doing certain things while my application is in background.
I am doing exactly as it is mentioned here: https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task
I have one separate project for Background Tasks and in my package manifest file I have declared that my app uses background tasks (but "timer" task since I am using TimerTrigger). Code:
BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder { Name = "NotificationUpdater", TaskEntryPoint = "NamespaceOfMyBackgroundTaskInterfaceImplementation.BackgroundTask"};
backgroundTaskBuilder.SetTrigger(new TimeTrigger(15, false));
BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
Now, when I launch my app (via Visual Studio), and use Lifecycle Events dropdown to suspend my app, it never executes the Run() method in the BackgroundTask class (implementation of IBackgroundTask interface).
Code inside BackgroundTask class:
namespace NamespaceOfMyBackgroundTaskInterfaceImplementation
{
public sealed class BackgroundTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
//Code to run in the background
}
}
}

As it turned out in the conversation, the problem was in wrong declaration of project type. In should be a Windows Runtime Component.
For the followers, please take a look at this answer, which describes the steps. It answers to Silverlight 8.1, but the process and steps are the same in WinRT and UWP.

Related

Can I manually run a C# class containing a Main() method from a project that is not a console application project?

I am pretty new in .NET\C# (I came from Java) and I have the following doubt.
In my solution I have a project that should be a SharePoint job, something like this in my solution explorer:
I know that this project is deployed as a SharePoint job and it works fine.
Now I have the need to manually perform a specific operation that is in some way related to this job. So my idea was to create this MigrateAttachments class into this project and put a Main() method here, then perform only this class as a script:
namespace XXXMigrationJob
{
class MigrateAttachments
{
static void Main(string[] args)
{
Debug.Print("MigrateAttachments Main() START");
Debug.Print("MigrateAttachments Main() END");
}
}
}
But it seems to me that I can't perform this Main() method as a standalone method and that the only way to do it is to create a brand new Console Application project that will contain this class.
is it true or am I missing something and I can manually run this MigrateAttachements Main() method also into my XXXMigrationJob project?
No you can't really just execute that. It will be in a DLL not an exe. You'll need to bootstrap it somehow.
I would refactor the reusable code into a class library. Then create a console app as you mentioned. Reference the reusable class library and call it.
However if you don't want to create a console app, then the link NineBerry put in discusses calling .net code with PowerShell and Reflection.

Threads in JSF?

I new in JSF, and I need use Threads for google maps. I am using primefaces for google maps, but I need excute a thread in background to get lat and long from data base and then graphic the markers in the map.
Your question is not specific to JSF, but rather to web applications in general. So, how to perform tasks asynchronously in a Java web applications? Definitely NOT by creating your own threads.
A Java web application runs in an application server (for example jBoss). It is the responsibility of the application server to manage Java threads for you. For instance, it will use a separate thread for each web request that comes in. The application server creates a pool of threads and reuses those threads since it is somewhat expensive to create new ones all the time. That's why you should not create your own, especially if it's done for every web request since it will directly impact scalability.
In order to execute tasks asynchronously, you can use the ejb #Asynchronous annotation (assuming the app is running in a Java EE container like jBoss, but not Tomcat).
import javax.ejb.Singleton;
#Singleton
public class AsyncBean {
#Asynchronous
public void doSomethingAsynchronously() {
// when this EJB is injected somewhere, and this method is called, it will return to the caller immediately and its logic will run in the background
}
}
If the app is not running in a Java EE container, take a look at this answer which nicely lays out some other options for async processing in web apps.
JSF is completely unrelated to your problem. For this case, JSF will act as mere HTML generator. Your specific problem is how to prepare data asynchronously and consume it from your web app.
You can create the thread manually when the application starts on a class that implements ServletContextListener interface, like this:
public class ApplicationListener implements ServletContextListener {
ExecutorService executor;
public ApplicationListener() {
executor = Executors.newSingleThreadExecutor();
}
#Override
public void contextInitialized(ServletContextEvent sce) {
Runnable task = new Runnable() {
#Override
public void run() {
//process the data here...
}
}
executor.submit(task);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
executor.shutdownNow();
}
}
Improve the design above to fulfill your requirements. Take into account that creating threads in an application server should only be done if you know what you're doing.
Another implementation would be to use another application to do the processing (let's call it Data Processor), which by default will run on a separate thread and environment. Then, communicate your web application with this Data Processor through a cache or nosql application like EhCache, Infinispan or Hazelcast.

Ninject dependency injection in SharePoint Timer Job

I have successfully implemented an enterprise SharePoint solution using Ninject dependency injection and other infrastructure such as NLog logging etc using an Onion architecture. With a HttpModule as an Composition Root for the injection framework, it works great for normal web requests:
public class SharePointNinjectHttpModule: IHttpModule, IDisposable
{
private readonly HttpApplication _httpApplication;
public void Init(HttpApplication context)
{
if (context == null) throw new ArgumentException("context");
Ioc.Container = IocContainerFactory.CreateContainer();
}
public void Dispose()
{
if(_httpApplication == null) return;
_httpApplication.Dispose();
Ioc.Container.Dispose();
}
}
The CreateContainer method loads the Ninject modules from a separate class library and my ioc container is abstracted.
For normal web application requests I used a shared static class for the injector called Ioc. The UI layer has a MVP pattern implementation. E.g in the aspx page the presenter is constructed as follows:
presenter = Ioc.Container.Get<SPPresenter>(new Ninject.Parameters.ConstructorArgument("view", this));
I'm still reliant on a Ninject reference for the parameters. Is there any way to abstract this, other than mapping a lot of methods in a interface? Can't I just pass in simple types for arguments?
The injection itself works great, however my difficulty comes in when using external processes such as SharePoint Timer Jobs. It would obviously be a terrible idea to reuse the ioc container from here, so it needs to bootstrap the dependencies itself. In addition, it needs to load the configuration from the web application pool, not the admin web application. Else the job would only be able to run on the application server. This way the job can run on any web server, and your SharePoint feature only has to deploy configurations etc. to the web apllication.
Here is the execute method of my timer job, it opens the associated web application configuration and passes it to the logging service (nlog) and reads it's configuration from the external web config service. I have written code that reads a custom section in the configuration file and initializes the NLog logging infrastructure.
public override void Execute(Guid contentDbId)
{
try
{
using (var ioc = IocContainerFactory.CreateContainer())
{
// open configuration from web application
var configService = ioc.Get<IConfigService>(new ConstructorArgument("webApplicationName", this.WebApplication.Name));
// get logging service and set with web application configuration
var logginService = ioc.Get<ILoggingService>();
logginService.SetConfiguration(configService);
// reapply bindings
ioc.Rebind<IConfigService>().ToConstant(configService);
ioc.Rebind<ILoggingService>().ToConstant(logginService);
try
{
logginService.Info("Test Job started.");
// use services etc...
var productService = ioc.Get<IProductService>();
var products = productService.GetProducts(5);
logginService.Info("Got products: " + products.Count() + " Config from web application: " + configService.TestConfigSetting);
logginService.Info("Test Job completed.");
}
catch (Exception exception)
{
logginService.Error(exception);
}
}
}
catch (Exception exception)
{
EventLog.WriteError(exception, "Exception thrown in Test Job.");
}
}
This does not make the timer jobs robust enough, and there is a lot of boiler plate code. My question is how do I improve on this design? It's not the most elegant, I'm looking for a way to abstract the timer job operation code and have it's dependencies injected into it for each timer job. I would just like to hear your comments if you think this is a good approach. Or if someone has faced similar problems like this? Thanks
I think I've answered my own question with the presenter construction code above. When using dependency injection in a project, the injection itself is not that important, but the way it changes the way you write code is far more significant. I need to use a similar pattern such as command for my SharePoint timer job operations. I'd just like the bootstrapping to be handled better.

My custom Windows Service is not writing to my custom Event Log

I have written a custom Windows Service that writes data to a custom Event Log (in the Windows Event Viewer).
For dev'ing the biz logic that the service uses, I created a Windows Form which simulates the Start/Stop methods of the Windows Service.
When executing the biz logic via the Windows Forms, info is successfully written to my custom Event Log. However, when I run the same biz logic from the custom Windows Service, information is failing to be written to the Event Log.
To be clear, I have written a library (.dll) that does all the work that I want my custom service to do - including the create/write to the custom Event Log. My Form application references this library as does my Windows Service.
Thinking the problem is a security issue, I manually set the custom Windows Service to "Log on" as "Administrator", but the service still did not write to the Event Log.
I'm stuck on how to even troubleshoot this problem since I can't debug and step into the code when I run the service (if there is a way to debug a service, please share).
Do you have any ideas as to what could be causing my service to fail to write to the event log?
I use it like this. There can be some typos. Writed it on my phone browser...
public class MyClass
{
private EventLog eventLog = new EventLog();
public void MyClass()
{
if (!System.Diagnostics.EventLog.SourceExists("MyLogSource"))
System.Diagnostics.EventLog.CreateEventSource("MyLogSource", "MyLogSource_Log");
eventLog.Source = "MyLogSource";
eventLog.Log = "MyLogSource_Log";
}
private void MyLogWrite()
{
eventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
}
}
To debug a running service you need to attach to the process. See here for the steps.
You could also add parameter checking to the Main entry point and have a combination service and console app which would start based on some flag. See this SO post for a good example but here's a snippet:
using System;
using System.ServiceProcess;
namespace WindowsService1
{
static class Program
{
static void Main(string[] args)
{
if (args == null)
{
Console.WriteLine("Starting service...");
ServiceBase.Run(new ServiceBase[] { new Service1() });
}
else
{
Console.WriteLine("Hi, not from service: " + args[0]);
}
}
}
}
The above starts the app in console mode if there any parameters exist and in service mode if there are no parameters. Of course it can be much fancier but that's the gist of the switch.
I discovered why my service wasn't writing to the Event Log.
The problem had nothing to do with any part of the code/security/etc that was attempting to write to the EL. The problem was that my service wasn't successfully collecting the information that is written to the EL - therefore, the service wasn't even attempting to write the log.
Now that I fixed the code that collects the data, data is successfully writing to the event log.
I'm open to having this question closed since the question was amiss to the real problem.

Problems using an installclass in a web setup for a web site

I am trying to create a web setup for my web site, and I want to use an installer class to do some custom stuff. I am using VS 2010, and the web site and installer is .NET 3.5.
I have added reference to the installer class project output in the Install section under Custom Actions:
I have also set /targetdir="[TARGETDIR]/" on the CustomActionData for this action.
The InstallScript project is a standard class library (dll).
There is a public class that inherits from Installer class. It overrides the Install method as I have seen been done in several online examples:
using System.Collections;
using System.Windows.Forms;
namespace InstallScript
{
public class MyWebInstaller : System.Configuration.Install.Installer
{
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
var targetDir = Context.Parameters["targetdir"];
if(targetDir==null) targetDir = "No TARGETDIR!";
MessageBox.Show("TARGETDIR:\t" + targetDir);
}
}
}
I would think there should be shown a message box here som time during the install, but it seems like it is never called. No error is shown either. The setup just runs through as if this code was never called.
Anyone have idea of what is wrong?
OK, I found out what was missing.
You need to specify the class with the class attribute RunInstaller(true) for the setup to pick up and actually run the code.
So the class needs to be declared like this:
[System.ComponentModel.RunInstaller(true)]
public class MyWebInstaller : System.Configuration.Install.Installer
{
...

Resources