Portable Class Library - Windows Store App: "Could not load file or assembly Microsoft.Threading.Task" - windows-store-apps

I have an MVVM Light infrastructure which is all contained within a Portable Class Library targeting .Net 4, SL5, Win 8, WP 8.1, WPSL 8, Xamarin.Android and Xamarin.iOS. This works perfectly with a WPF client, however, when I try and use it in a Windows Store App/Win 8 environment I am coming up against some resistance. The first issue is found in App.xaml:
<Application
x:Class="Win8Client.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:INPS.Vision.Appointments.Shared.ViewModels"
xmlns:local="using:Win8Client">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" />
</Application.Resources>
</Application>
At design time I get "Could not load file or assembly 'Microsoft.Threading.Tasks', version=1.0.12.0 ..." which is referring to my ViewModelLocator. This compiles and appears to run ok but I don't get any design time data. The design time data works fine in the WPF client.
Once running I see my first view but once this line gets called:
Slots = await _appointmentsDataProvider.GetAppointments(SelectedDate);
I get the following exception in the setter of my slots property which takes advantage of MVVM Lights Set method of ViewModelBase. The Slots property is NOT bound to any UI yet.
Exception:
"The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))"
Slots Property:
public List<Slot> Slots
{
get { return _slots; }
set
{
Set(SlotsPropertyName, ref _slots, value); // <-- Exception thrown here
}
}
Realised I haven't actually asked a question. Simply, I would like to know, what is the best approach for using MVVM Light with a Windows Store App?
Thanks in advance for any help or advice!

The first issue "Could not load file or assembly 'Microsoft.Threading.Tasks', version=1.0.12.0 ..." I haven't worked out yet but from time to time I do see the design data. Seems very temperamental...
The second issue - The reason this through me a bit was because is "just worked" in WPF and I assumed it would just work in a Windows Store App. Wrong. It looks like Windows Store Apps handle async/await threading differently - that's my guess.
Fix: Created an IDispatcherHelper interface in PCL with a single method declaration:
void RunOnUIThread(Action action);
Then created a single concrete DispatcherHelper class in each platform specific project (WPF/Windows 8.1) which implement IDispatcherHelper. Each implementation simply calls MVVM Lights:
DispatcherHelper.CheckBeginInvokeOnUI(action);
In App.xaml.cs in the WPF and Windows 8.1 I simply registered the concrete implementations with MVVM Lights SimpleIoc with the IDispatcherHelper as the handle. Within the view model I then use the platform specific implementations through the interface:
var slots = await _appointmentsDataProvider.GetAppointments(SelectedDate);
IDispatcherHelper dispatcherHelper = SimpleIoc.Default.GetInstance<IDispatcherHelper>();
dispatcherHelper.RunOnUIThread(() =>
{
Slots = slots;
});
Got to love abstraction!

Related

How to navigate between pages in windows universal app using C++/CX

I am new to Windows universal app development. As per my knowledge Windows universal app can be made by using C++/CX , C# or JavaScript. But Microsoft force to do development by using C++/CX because it uses power of winRT much better than others. So i tried the development using C++/CX for Visual Studio 2015.
I come to a topic of Navigation. To perform navigation in app there is one API
this->Frame->Navigate(TypeName(MySecondPage::typeid)). This API gives me a exception at runtime.
This is the detail scenario what i did.
1. I create project by named NavigationSample using C++/CX.
Then i added new Basic Page of xaml for my Second view/ui and named it as MySecondPage.xaml
Now on first page i.e. MainPage.xaml i added One button.
On event of this button , lets say button_Click as event handler i wrote
this->Frame->Navigate(TypeName(MySecondPage::typeid))
Here is the detailed code:
void NavigationSample::MainPage::button_Click(**Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)**
{
this->Frame->Navigate(TypeName(MySecondPage::typeid));
}
This compile and build fine. But gives exception at runtime. (Same scenario works very fine with C#)
So guys please help me how to resolve this issue?
Thanks
Here's a clue:
m_ptrSettingsPage->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() {
m_ptrSettingsPage->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(AnnuitiesPage::typeid));
}));
Best wait for C++/wimRT

ServiceLocationProvider is null when launched as a Share Target

I'm using MVVM Light and everything is fine except when launching my Windows Phone 8.1 WinRT app as a Share Target.
When I try to assign MainViewModel viewModel = ServiceLocator.Current.GetInstance<MainViewModel>(); I get an exception for ServiceLocator.Current.
Exception Message: ServiceLocationProvider must be set.
Do I need to do something extra in App.xaml.cs OnShareTargetActivated event to insure the Locator is running?
UPDATE:
A ShareTarget page needs to be thought of as a small extension of your app. It seems that not all of the app's resources are loaded (including app-wide resources in App.xaml). So I just created a new instance of MainViewModel in the share page's constructor, loaded only the things I need for the share to complete, save the information and call ShareOperation.ReportCompleted. This returns the user back to the app that is sharing.
I still haven't found a good solution for getting other resources in my ViewModel, but this works for now.
This indicates that the following line has not been executed:
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
This line will instruct the ServiceLocator class to use the SimpleIoc.Default instance as its ServiceLocator.Current. When you run your app as a Share target, the initialization is slightly different and probably the ViewModelLocator doesn't get initialized. You need to find a good location to perform the initialization before you use the ServiceLocator.
Cheers
Laurent

Use MessageDialog/MessageBox with Portable Class Library and MVVM Light

I´m developing an App that will be available for Windows Phone 8 and the Windows Store. To reduce redundancy I´m using a Portable Class Library (PCL) and on top of that I'm trying to apply the MVVM pattern with the help of the MVVM Light PCL Toolkit. The ViewModels are placed in the PCL and are bound directly in the XAML of the Apps pages.
When the data is received without an error, everything works fine. But I don´t know how to get the exceptions/error message back to the App when errors do happen.
Inside the Windows Store App errors will show as a MessageDialog while the Wp8 App will use the MessageBox class. Obviously the PCL isn´t aware of any of these classes. What I´m not getting is how to know if a ViewModel ran into an error, and how to get the message inside the App. Is this even possible when the ViewModels are bound inside the XAML?
The code in the ViewModel (inside the PCL) looks like this:
DataService.Authenticate((token, error) =>
{
if (error != null)
{
// This is, obviously, not going to work.
MessageBox.Show(error.Message);
return;
}
Token = token;
});
So I have to save the error somehow and let the App itself know the error has occurred, and then call the matching way of showing the error to the user.
Currently I´m thinking of something like defining an Error-property inside the BaseViewModel and fill it when errors in the ViewModel occur. Then, in the CodeBehind of the pages, make them aware of the current ViewModel and bind a PropertyChanged-event to this Error-property. But I was not able to implement it yet, so I don't know if this is even the right way to go.
Do I have to step down from the idea to bind the ViewModels inside the XAML, and do I instead have to initialize them inside the pages Codebehind?
Your instinct is correct, but there are more than a few ways of going about this.
First and foremost, you can use Mvvm's Messaging library, which will allow your ViewModel to send messages directly to your View. Your View can then handle it in any way it wishes, including but not limited to using a MessageDialog.
Secondly, you can also create a Function or Action (likely the former) in your ViewModelLocator for ShowMessageDialog. This Function will likely take a string and return a Task. Then, after you initialize your ViewModelLocator initially, you can inject your ShowMessageDialog code. Your ViewModels can then use whatever platform's MessageDialogs that they please.
Ex:
Note: This code uses the BCL Async libraries that are accessible in Nuget. They work in the PCL just fine.
ViewModelLocator:
public static Func<string, Task> ShowMessageDialog { get; set; }
App.xaml.cs:
ViewModelLocator.ShowMessageDialog = (message) =>
{
// For Windows Phone
return TaskFactory.StartNew(() => MessageBox.Show(message));
// For Windows 8
MessageDialog md = new MessageDialog(message);
return md.ShowAsync().AsTask();
};
ViewModel:
await ViewModelLocator.ShowMessageDialog("This is my message.");
Secondary Note: The md.ShowAsync().AsTask(); must be run on the UI Thread. This means that you will have to invoke it via the dispatcher in the case that you are running it in a task asynchronously. This is possible using a similar method of injecting the use of the app's CoreDispatcher via the RunAsync method.
This means that you can, on any platform (Windows 8 and Windows Phone shown above), inject whatever Message Dialog system you want and use it in your PCL.
I would say that it is much easier to do the first method I suggested, as that is what it is there for, but the Function method version is definitely helpful at times.

swing uncaughtexceptionhandler

I am trying to build a general exception handler for a swing application as described here: http://www.javaspecialists.eu/archive/Issue081.html
I work in jython (python syntax getting compiled to java and executed). My code looks roughly like this (updated):
def launcher(func):
class launcherThread(Runnable):
def __init__(self):
super(launcherThread, self).__init__()
def run(self):
func()
#trying to get the name which can be used to instantiate this in java
cls = ExceptionGroup().getClass()
fullName = cls.__module__ + '.' + cls.__name__
System.setProperty("sun.awt.exception.handler", fullName)
Thread(ExceptionGroup(), launcherThread(), 'Cross ExceptionHandlerThread').start()
class ExceptionGroup(ThreadGroup):
def __init__(self):
super(ExceptionGroup, self).__init__("HardenedGroup")
def uncaughtException(self, thread, exception):
#make a fancy dialog displaying str(exception)
If I test it it works fine however in the production enviornment it failes.
For testing I launch my program in Eclipse (PyDev), the production enviornment is a third party application written in Java, that has a Jython console build in. The application supports adding of custom menu entries, and putting jython scripts on these.
The main difference I see between testing and production enviornment is that in the production enviornment the swing threads are allready started (the third party application utilitizes swing). Does this cause my ThreadGroup setting to fail, or is there another reason why this is not working?
How can I get the Involved threads (exceptions ar thrown as a result of buttonActions) to check their defaultException handlers? If (as I am afraid) it should turn out that the third party installed its own handler (all exceptions are written to a log file) how can I make a new swing worker thread? (I don't want to catch the exceptions created by the host application after all)
Question recap:
1. How can I check which threads are started for the function func passed into the launcher function and see thier uncaught exception handler?
2. Can I enforce a seperate swing dispatcher for my gui part and the main applications gui part? (If I exitOnClos on a frame of my add in, the third party application closes)?
Update:
Considering the anwser from lbalazscs I am trying to use the sun.awt.exception.handler property, but it has no effect, the exceptions still end up in the log file (applications dfeault behaviour). Am I using it right? (p.s.: I am on Java 1.6)
If you have Java 5 or higher, you can also use Thread.setDefaultUncaughtExceptionHandler(), which is also described in a newer "Java Specialists' Newsletter":
http://www.javaspecialists.eu/archive/Issue089.html
And here is the newest Java 7 version:
http://www.javaspecialists.eu/archive/Issue196.html
Also see this:
Why bother with setting the "sun.awt.exception.handler" property?
EDIT: This is how I use Thread.setDefaultUncaughtExceptionHandler (in Java...):
public static void setupGlobalExceptionHandling() {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
handleException(e);
}
});
}

MEF: "Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information"

Scenario: I am using Managed Extensibility Framework to load plugins (exports) at runtime based on an interface contract defined in a separate dll. In my Visual Studio solution, I have 3 different projects: The host application, a class library (defining the interface - "IPlugin") and another class library implementing the interface (the export - "MyPlugin.dll").
The host looks for exports in its own root directory, so during testing, I build the whole solution and copy Plugin.dll from the Plugin class library bin/release folder to the host's debug directory so that the host's DirectoryCatalog will find it and be able to add it to the CompositionContainer. Plugin.dll is not automatically copied after each rebuild, so I do that manually each time I've made changes to the contract/implementation.
However, a couple of times I've run the host application without having copied (an updated) Plugin.dll first, and it has thrown an exception during composition:
Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information
This is of course due to the fact that the Plugin.dll it's trying to import from implements a different version of IPlugin, where the property/method signatures don't match. Although it's easy to avoid this in a controlled and monitored environment, by simply avoiding (duh) obsolete IPlugin implementations in the plugin folder, I cannot rely on such assumptions in the production environment, where legacy plugins could be encountered.
The problem is that this exception effectively botches the whole Compose action and no exports are imported. I would have preferred that the mismatching IPlugin implementations are simply ignored, so that other exports in the catalog(s), implementing the correct version of IPlugin, are still imported.
Is there a way to accomplish this? I'm thinking either of several potential options:
There is a flag to set on the CompositionContainer ("ignore failing imports") prior to or when calling Compose
There is a similar flag to specify on the <ImportMany()> attribute
There is a way to "hook" on to the iteration process underlying Compose(), and be able to deal with each (failed) import individually
Using strong name signing to somehow only look for imports implementing the current version of IPlugin
Ideas?
I have also run into a similar problem.
If you are sure that you want to ignore such "bad" assemblies, then the solution is to call AssemblyCatalog.Parts.ToArray() right after creating each assembly catalog. This will trigger the ReflectionTypeLoadException which you mention. You then have a chance to catch the exception and ignore the bad assembly.
When you have created AssemblyCatalog objects for all the "good" assemblies, you can aggregate them in an AggregateCatalog and pass that to the CompositionContainer constructor.
This issue can be caused by several factors (any exceptions on the loaded assemblies), like the exception says, look at the ExceptionLoader to (hopefully) get some idea
Another problem/solution that I found, is when using DirectoryCatalog, if you don't specify the second parameter "searchPattern", MEF will load ALL the dlls in that folder (including third party), and start looking for export types, that can also cause this issue, a solution is to have a convention name on all the assemblies that export types, and specify that in the DirectoryCatalog constructor, I use *_Plugin.dll, that way MEF will only load assemblies that contain exported types
In my case MEF was loading a NHibernate dll and throwing some assembly version error on the LoaderException (this error can happen with any of the dlls in the directory), this approach solved the problem
Here is an example of above mentioned methods:
var di = new DirectoryInfo(Server.MapPath("../../bin/"));
if (!di.Exists) throw new Exception("Folder not exists: " + di.FullName);
var dlls = di.GetFileSystemInfos("*.dll");
AggregateCatalog agc = new AggregateCatalog();
foreach (var fi in dlls)
{
try
{
var ac = new AssemblyCatalog(Assembly.LoadFile(fi.FullName));
var parts = ac.Parts.ToArray(); // throws ReflectionTypeLoadException
agc.Catalogs.Add(ac);
}
catch (ReflectionTypeLoadException ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
}
CompositionContainer cc = new CompositionContainer(agc);
_providers = cc.GetExports<IDataExchangeProvider>();