BackgroundTask UWP C++ trigger only one time? - c++

In windows runtime component project (BackgroundTask c++)
#include "pch.h"
#include "BackgroundTask.h"
using namespace Platform;
namespace SyncBackground {
void BackgroundTask::Run(IBackgroundTaskInstance^ taskInstance) {
_taskInstance = taskInstance;
taskInstance->Canceled += ref new BackgroundTaskCanceledEventHandler(this, &BackgroundTask::OnCanceled);
_deferral = taskInstance->GetDeferral();
OutputDebugString(L"Debug: CPP\r\n");
}
void BackgroundTask::OnCanceled(IBackgroundTaskInstance^ sender, BackgroundTaskCancellationReason reason) {
_deferral->Complete();
}
}
I try ApplicationTrigger from c# project, but OutputDebugString write only one times from first trigger. In the same BackgroundTask C#, Debug.WriteLine() write every trigger.
Then why in c++ do it only one times? And how make it work look like c# (i need send some data and command via trigger)
Thank

I need it still run background
If I understand correctly, you just want to run background tasks indefinitely. If so, even if you don't call TaskDeferral.Complete();, it won't still run background, after a period of time, it will still be terminated. In that case, you can refer to this document to configure. But it mentions if you use it, you can't put an app into the Microsoft Store. If not, please point me out.

Related

uwp: How download files when app is in suspended mode

There is queue with links of files to download. I'm trying find the way to continue downloading when application goes to suspend mode.
According to official microsoft documentation suitable class for this is BackgroundDownloader, but it's handles only one current downloading process. It looks wrong to call in loop CreateDownload() method for every link without waiting for the completion of previous links, isn't right?
More logical in my opinion is using in-process background task. I see it this way:
Implement Run(IBackgroundTaskInstance) method of interface IBackgroundTask (it should stay alive even when app is suspended, right?)
Using custom event transmit the queue to the implemented method
Inside Run(IBackgroundTaskInstance) method use BackgroundDownloader (by implementing the execution of one instance at a time)
But I'm stuck even with simple implementation for one file downloading. Bellow my Run(IBackgroundTaskInstance) method implementation:
void Task::DownloaderTask::Run(IBackgroundTaskInstance ^ taskInstance)
{
TaskDeferral = taskInstance->GetDeferral();
std::wstring filename = L"Pleiades_large.jpg";
Uri^ uri = ref new Uri(ref new Platform::String(L"https://upload.wikimedia.org/wikipedia/commons/4/4e/Pleiades_large.jpg"));
Concurrency::create_task(KnownFolders::GetFolderForUserAsync(nullptr, KnownFolderId::PicturesLibrary))
.then([this, filename, uri](StorageFolder^ picturesLibrary)
{
return picturesLibrary->CreateFileAsync(ref new Platform::String(filename.c_str()), CreationCollisionOption::GenerateUniqueName);
}).then([this, filename, uri](StorageFile^ destinationFile) {
BackgroundDownloader^ downloader = ref new BackgroundDownloader();
DownloadOperation^ download = downloader->CreateDownload(uri, destinationFile);
download->StartAsync();
}).then([this](Concurrency::task<void> previousTask)
{
try
{
previousTask.get();
TaskDeferral->Complete();
}
catch (Platform::Exception^ ex)
{
wchar_t buffer[1024];
swprintf_s(buffer, L"Exception: %s", ex->Message);
OutputDebugString(buffer);
}
});
}
The code above only creates empty file, but using the same code without BackgroundTask it works correctly. I didn't find any restrictions for BackgroundDownloader inside BackgroundTask.
So, my questions are:
Is it right way of usage BackgroundTask?
Is there another approach to solving the problem?
Is this problem solvable at all?
I've found the cause of the unexpected behavior:
The line of code TaskDeferral->Complete(); was at the end of the method at first while it should be at the end of async call.
Therefore, initial implementation (published in question) is correct.
All that had to be done was to Rebuild project.

Google Play Services C++ / Run UI on second activity using IntentHandler

I am developing a mobile game using Cocos2D-x engine for android platform and i want to integrate GPGS on it.
I achieved to show leaderboards, but there is a little annoying problem. When leaderboard is visible, if i go background and then come back to app, the gamescene goes to black. I think opengl context being released and doesnt restore again. In my opinion running leaderboard on same activity causes this, the game engine cant understand whats happening there. Whatever, because of this I want to run leaderboard (and also all GPGS things) on a new activity using intent.
Google likes "Providing"
In the reference documents of Google Play Game Services C++ SDK, there is a few unclear/fuzzy explanation about using SetOptionalIntentHandlerForUI method.
"Provide a function that can start a provided UI intent at any point, using startActivityForResult."
What is the mean of "Providing"? What is a provided Intent? How will I use startActivityForResult method? Unfortunately, "using" and "providing methods" are not clear expressions for coding. There is no sample about
using this method in the documents of GPGS for C++. Eventually,
Google's document is so poor and
there is no useful information on the internet. If someone from Google helps me, I will be so happy.
As i understand, I wrote the code like this. But it gives error when starting.
AppActivity.java
public void runGPGSActivity(Intent i) {
startActivityForResult(i,100);
}
AndroidPlatformConfiguration.h (From C++ gpg lib)
typedef std::function<void(jobject)> IntentHandler;
AndroidPlatformConfiguration &SetOptionalIntentHandlerForUI(
IntentHandler intent_handler);
main.cpp (JNI binding, the working code, GPGS runs on same activity )
gpg::AndroidPlatformConfiguration platform_configuration;
platform_configuration.SetActivity(activity);
StateManager::InitServices( ...
main.cpp (JNI binding, GPGS must be run on new activity )
gpg::AndroidPlatformConfiguration platform_configuration;
jclass activityClass = env->FindClass("org/cocos2dx/cpp/AppActivity");
jmethodID jIntentHandlerMethodID = env->GetMethodID(activityClass,"runGPGSActivity","(Landorid/content/Intent;)V");
jobject jIntentHandler = env->NewObject(activityClass, jIntentHandlerMethodID);
gpg::AndroidPlatformConfiguration::IntentHandler mIntentHandler; /*= [](jobject mjIntentHandler){};*/
std::function<void(jobject)> intentHandler = std::bind(mIntentHandler,jIntentHandler);
platform_configuration.SetOptionalIntentHandlerForUI(intentHandler);
platform_configuration.SetActivity(activity);
StateManager::InitServices(
There is no build error, but the application crashes when launching.
03-24 14:12:24.301: A/libc(21352): Fatal signal 6 (SIGABRT) at
0x00005368 (code=-6), thread 21352 (main)
And some links about this issue:
IntentHandler reference
StartActivityForResult reference
/// Thank you in advance. ///
...Yeah I solved the problem, but didn't use IntentHandler method.
I was using this code in my app, to show weekly leaderboard data.
gameServices->Leaderboards().ShowUIBlocking(leaderboardId,gpg::LeaderboardTimeSpan::WEEKLY);
But return value is not void, it is UIStatus (whatever it is)
I've reverted back to this code, app is not going to black screen now. This method returns void, I think I have to catch some callbacks when using ShowUIBlocking method, with that UIStatus thing.
gameServices->Leaderboards().ShowUI(leaderboardId);
But now, I can't benefit from timespan feature of leaderboards.
I am going to research how it can be used. There is no problem for now. But, documentation of SetOptionalIntentHandlerForUI must be written more explicit, for programmers who want to use it.

How to test asynchronuous code

I've written my own access layer to a game engine. There is a GameLoop which gets called every frame which lets me process my own code. I'm able to do specific things and to check if these things happened. In a very basic way it could look like this:
void cycle()
{
//set a specific value
Engine::setText("Hello World");
//read the value
std::string text = Engine::getText();
}
I want to test if my Engine-layer is working by writing automated tests. I have some experience in using the Boost Unittest Framework for simple comparison tests like this.
The problem is, that some things I want the engine to do are just processed after the call to cycle(). So calling Engine::getText() directly after Engine::setText(...) would return an empty string. If I would wait until the next call of cycle() the right value would be returned.
I now am wondering how I should write my tests if it is not possible to process them in the same cycle. Are there any best practices? Is it possible to use the "traditional testing" approach given by Boost Unittest Framework in such an environment? Are there perhaps other frameworks aimed at such a specialised case?
I'm using C++ for everything here, but I could imagine that there are answers unrelated to the programming language.
UPDATE:
It is not possible to access the Engine outside of cycle()
In your example above, std::string text = Engine::getText(); is the code you want to remember from one cycle but execute in the next. You can save it for later execution. For example - using C++11 you could use a lambda to wrap the test into a simple function specified inline.
There are two options with you:
If the library that you have can be used synchronously or using c++11 futures like facility (which can indicate the readyness of the result) then in your test case you can do something as below
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (!Engine::isResultReady());
//read the value
assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT");
}
If you dont have the above the best you can do have a timeout (this is not a good option though because you may have spurious failures):
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") {
wait(1 millisec);
if (total_wait_time > 1 sec) // you can put whatever max time
assert(0);
}
}

Managed C++ Wrapper for Unmanaged Static Library with static variables hangs

The explanation of the problem is a little long-winded, please bear with me.
I have an unmanaged C++ static library that is used for financial application. It has business day conventions, swap conventions, bond conventions, etc. Most of the conventions rely on static global variables, which are initialized on first use. The library also initializes the holiday calendars on startup by running some queries against a SQL Server database using ODBC.
I have to interact with third-party software using web services. The only way to do this realistically is through C#. That isn't an issue, and I was making good progress. However, I hit a stumbling block when it became necessary to do some date calculations in C#. Since I didn't want to port all my C++ code to C#, I figured the most efficient way to achieve this would be by writing a Managed C++ Class Library DLL that is a wrapper around my unmanaged static library. Everything seems to work fine, I get no compile-time or link-time errors, and I can add the reference to the wrapper and see all the proper object definitions. However, when I try to run my application, it just hangs. I have tried playing around with a bunch of compiler setting for the wrapper DLL, to no avail. If I remove the project dependency on my unmanaged library, everything works fine. I have a strong suspicion that my liberal use of global static variables is causing issues. Is there are way to solve this problem, are at least figure out where the issue is? Example code is below.
Thanks,
Marc.
// FSAManaged.h
#pragma once
using namespace System;
//class XLDate;
namespace FSAManaged {
public ref class Futures
{
public:
static DateTime Expiry(String ^ code, DateTime date);
};
}
The implementation does not even rely on a dependency to the unmanaged static library:
// This is the main DLL file.
#include "stdafx.h"
#include "FSAManaged.h"
namespace FSAManaged
{
DateTime Futures::Expiry(String ^ code, DateTime date) {
return DateTime::Today;
}
}
For completeness' sake, here is AssemblyInfo.cpp:
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("FSAManaged")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("?????")];
[assembly:AssemblyProductAttribute("FSAManaged")];
[assembly:AssemblyCopyrightAttribute("??????")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
Use the debugger. If you test this from C# then Project + Properties, Debug, tick "Enabled unmanaged code debugging". Setting up the symbol server in Tools + Options, Debugging, Symbols is strongly recommended. Run.
When it hangs use Debug + Break All. Debug + Windows + Threads and double-click the thread that is supposed to be doing the job. Debug + Windows + Call stack to see what is going on. Post the stack trace in your question if you can't figure it out. Anything you see in the Output window and the Visual Studio status bar is relevant too.
Static C++ variables are initialized from DllMain. There are lot's of things you should not do in DllMain; triggering the load of yet another Dll being the most important one. This is easy to break if you call into other peoples libraries in from DllMain.
I suggest you make an Init function on your Dll, which you call after the dll is up and running.

Problem debugging C++ with an Eclipse based IDE

This is a weird question in that I'm not sure where to start looking.
First of all, I haven't done any C++ programming for the last 10 years so it could be me thats forgotten a few things. Secondly, the IDE I'm using is Eclipse based (which I've never used) and customized for Samsung bada based mobile development (it kicks off an emulator for debugging purposes)
I'm posting my code samples as images because the StackOverflow WYSIWYG editor seems to have a problem parsing C++.
[EDIT] Due to complaints I've edited my question to remove the images. Hope that helps :)
I have the following header file...
#include <FApp.h>
#include <FBase.h>
#include <FGraphics.h>
#include <FSystem.h>
#include <FMedia.h>
using namespace Osp::Media;
using namespace Osp::Graphics;
class NineAcross :
public Osp::App::Application,
public Osp::System::IScreenEventListener
{
public:
static Osp::App::Application* CreateInstance(void);
public:
NineAcross();
~NineAcross();
public:
bool OnAppInitializing(Osp::App::AppRegistry& appRegistry);
private:
Image *_problematicDecoder;
};
...and the following cpp file...
#include "NineAcross.h"
using namespace Osp::App;
using namespace Osp::Base;
using namespace Osp::System;
using namespace Osp::Graphics;
using namespace Osp::Media;
NineAcross::NineAcross()
{
}
NineAcross::~NineAcross()
{
}
Application* NineAcross::CreateInstance(void)
{
// Create the instance through the constructor.
return new NineAcross();
}
bool NineAcross::OnAppInitializing(AppRegistry& appRegistry)
{
Image *workingDecoder;
workingDecoder->Construct();
_problematicDecoder->Construct();
return true;
}
Now, in my cpp file, if I comment out the line that reads _problematicDecoder->Construct();...I'm able to set a breakpoint and happily step over the call to Constuct() on workingDecoder. However, as soon as I uncomment the line that reads _problematicDecoder->Construct();... I end up with the IDE telling me...
"No source available for "Osp::Media::Image::Construct()"
In other words, why can I NOT debug this code when I reference Image *image from a header file?
Any ideas?
Thanks :-)
This usually means you're stepping through some code which you do not posses its source.
I assume here that Osp::Media::Image is a class supplied by Samsung or similar for which you do not have the cpp file. So this means the debugger can't show you the current code line while you're at a function of Osp::Media::Image.
Alternatively, there's a good chance you do have all of the source code for this class, but Eclipse doesn't know where it is. In this case you can add the correct directories under the Debug Configurations window.
Ok, problem solved.
The idea is to first new up an instance of Image like so...
_decoder = new Osp::Media::Image();
And then do _decoder->Construct().
Funny enough, this seems blatantly obvious to me now coming from the C# world, though why the code I posted for workingDecoder works is still somewhat mysterious to me. The fact the sample projects pre-loaded with the bada IDE don't seem to make a call to new() leads me to believe that perhaps those samples are outdated our out of synch.
Either that or I really AM wildly out of the C++ loop.
Anyway thanks so much for the effort guys.
Appreciated :)