Author Archives: thomas@kison.info

Adventures with DelayedAction (C#)

Today I worked on a project and found a piece of code, that left me wondering what the one who wrote it was actually thinking this should do. I know what the code is intended to do, but it was so weird, I wanted to share and try to find a better solution.

First of all the code, I didn’t copy & paste it, I wrote it from memory, my brain memory 🙂

Don’t copy and paste this

CancellationTokenSource _cancellationTokenSource = null;
        private async void SetText()
        {

            try
            {
                if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested)
                {
                    _cancellationTokenSource.Cancel();
                }
                Interlocked.Exchange(ref _cancellationTokenSource, new CancellationTokenSource());
                await Task.Delay(2000, _cancellationTokenSource.Token);
                DoSearch();
            }
            catch
            {
            }
            finally
            {
                if (!_cancellationTokenSource.IsCancellationRequested)
                    _cancellationTokenSource.Cancel();
                _cancellationTokenSource.Dispose();
            }

        }

Any idea, what this is all about?
So let me just lift the curtain here. The function is being called within the Property-Setter, which is bound to an Entry. DoSearch() is just taking the Text and performing a full text search through a list of data. The challenge here is, that we don’t want to trigger the search on each keystroke, but when the user pauses for a second (or two in this case). Technically this code is producing a CancellationToken on each keystroke, waits 2 seconds, and cancels the previous delay task. TaskCanceledExceptions will be tolerated and ignored.

Try to make it better

If you have no clue, why this is bad code, you should just leave now. Really, go away. Let’s try to find a better solution. How about a counter? Let’s think of it like house, and every keystroke is a person going into that house. It’s a very special house, people are only visiting the house 2 seconds, then they leave. It’s not a brothel, maybe it stinks in the house, so the people leave right away. We stand at the port and count everyone that’s going and subtracting the peopel going out. After we reach to zero, we just close the door and go home, or whatever action we intent.

 public class DelayedAction
    {
        private Action _action;
        private int _callCounter = 0;
        private TimeSpan _delay = TimeSpan.FromSeconds(1);
        public DelayedAction(Action action)
        {
            _action = action;
        }

        public DelayedAction SetDelay(TimeSpan delay)
        {
            _delay = delay;
            return this;
        }

        public async void Trigger()
        {
            Interlocked.Increment(ref _callCounter);
            // now wait
            await Task.Delay(_delay);
            Interlocked.Decrement(ref _callCounter);
            if (_callCounter == 0)
            {
                _action();
            }

        }
    }

That’s it! Just a counter. No Exceptions, no CancellationTokens. We still have the Task.Delay but that’s way better than doing a SpinWait or BusyWait.

And here is how you can use it:

string _text;
DelayedAction _callSearchAction;
public MainPageViewModel(INavigationService navigationService)
    : base(navigationService)
{
    _callSearchAction = new DelayedAction(DoSearch)
                        .SetDelay(TimeSpan.FromMilliseconds(2000)); 
}


public string Text {
    get => _text;
    set
    {
        SetProperty(ref _text, value);
        //SetText();
        _callSearchAction.Trigger();
    }   
}

What’s wrong with those ObservableCollections and Threading?

When you are developing Apps with Xamarin.Forms you probably used ObservableCollections more than once. That’s pretty neat, because an ObservableCollection notifies the View on any changes that occur, so you don’t have to care about updating the Views.

A common use case is as follows. You have a list of items (models) that are being read from a database. The items are being transformed to ItemViewModels and added to a ObservableCollection. This ObservableCollection is bound to a ListView, which will be updated as soon as the item is being added. When you are lucky, and the whole transformation thing takes a lot of time, you will see every item being added subsequently.

ObservableCollection bound to a CollectionView

Looks awesome, you can still interact with the UI while the list is being generated. BUT .. that only works in a perfect world. There are several reasons, why creating a ListItem isn’t as easy as 1-2-3 (like in my example). Let’s say it takes 20ms or even more, to create one item. Your UI will probably freeze:

the UI blocks while filling the list

The users of your App will not like that. I don’t like it either, when an App shows such a bad behavior. But as always, it’s compilacted… The easiest (very uncommon) way to solve that problem is to even extend the time, fight fire with fire :-). Yes it’s easy to do but in my opinion bad practice.

If you ever developed with Windows Forms, you probably know of Application.DoEvents(). That gives the UI Thread time to work through the message pipe and handle keyboard presses and UI updates. There are two ways in Xamarin.Forms (probably also works in WPF) to do this, just use one of those two commands within your loop, that is adding the items to you ObservableCollection. This gives the UI enough time to redraw the screen:

await Task.Yield()
await Task.Delay(10)

   
            for (int i=0; i<100; i++)
            {
                //await Task.Delay(1);
                await Task.Yield();
                // do something that realy takes time
                DoSomething();
                Items.Add(new ItemViewModel
                {
                    Text = $"Item {i}",
                    MoreText = $"Some more text to Item {i}"
                });
            }

That works in a lot of cases, but maybe the whole process is to complex to do this. You could refactor and clean up your whole code (I would recommend that in the first place anyway). But putting the whole stuff on a new thead sound easier, and now we introduce the problem with Threading + ObservableCollection. You will probably get the following error:

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

And guess what, it’s not a problem of the ObservableCollection, the ObservableCollection actually is not thread safe (as all non-concurrent collections in .Net), but the ObservableCollection doesn’t care about the thread you make changes from. The problem is the ListView, that the Items are bound to. It assumes, that changes on the collection are made from the MainThread and just handles the UI updates. And UI updates are, as we know, thread affine, so you can only add elements to the View when you are in the same thread as it is being created on (the main thread, also called UI thread). In the current version of Xamarin they introduced a control, that can easily handle that: CollectionView. That’s the control of choice, if you encounter the problem I mentioned above.

Always prefer the usage of CollectionView instead of ListView.

What if you can’t switch to CollectionView?

One thing you can do is to call Device.BeginInvokeOnMainThread(), but be careful with that, an invoke on the MainThread is always very expensive, you should only use it when you have no other choice. (refactoring included)

for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(500);
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Items.Add(new ItemViewModel
                        {
                            Text = $"Item {i}",
                            MoreText = $"Some more text to Item {i}"
                        });
                    });
                }

Using async/await in an IValueConverter in Xamarin.Forms

Let’s start out with a very simple Setting – we have the following Models:
Product
+ Id : string
+ Name: string
+ Image: Image

Image
+ Id: string
+ Filename: string

In our service layer, we have a function that gets all products, and we want to show them on a Xamarin.Forms page, including each image. The Image-Model has no byte-data or whatsoever included. There is a special ImageCacheService implemented, that uses the Image to get the data either from disk (cache) or from a WebApi. This function is implemented using the async/await-pattern. So we have to use an async-context to get the data.
Here is how the ViewModel and Xaml looks like:

 public class MainPageViewModel
    {
        
        private ProductsService _productsService;
        public MainPageViewModel(ProductsService productsService)
        {
            _productsService = productsService;
            InitAsync();
        }

        private async void InitAsync()
        {
            var products = await _productsService.GetProducts();
            products.ForEach(Products.Add);
        }

        public ObservableCollection<Product> Products { get; } = new ObservableCollection<Product>();
    }
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AsyncConverter.MainPage">
   <CollectionView>
       <CollectionView.ItemTemplate>
           <DataTemplate>
               <Grid ColumnDefinitions="300,*">
                  <Image Source="" /> <!-- ??? how to bind image -->
                  <Label Grid.Column="1" Text="{Binding Name}" />
               </Grid>
           </DataTemplate>
       </CollectionView.ItemTemplate>
   </CollectionView>
</ContentPage>

So how to solve that problem? We somehow need to call await ImageCacheService.GetImageData(Image) on each Image to retrieve the data. The most common approach is to use ViewModels instead of direct Model binding. But we only want to show the product’s images on a page, we don’t want to change something. So why creating two(?) ViewModels that have no added value?

A more sophisticated approach would be to create an IValueConverter implementation, so we can just bind the Image-Model and the converter does the magic to retrieve the image from database/web/file system or wherever it is stored. However, if you try this implementation, you will quickly reach your limits. IValueConverter has no async pendant, so you can’t use it directly. But how about the following idea:

The converter doesn’t return an ImageSource, but it returns a ViewModel, with a property called something like “Result”. And as soon as the image data is retrieved, it will set the Result property and raise a PropertyChanged event, so that the UI can use it.

The implementation will look something like that:

public abstract class AsyncConverter<T> : IValueConverter
    {
        public abstract Task<T> AsyncConvert(object value, Type targetType, object parameter, CultureInfo culture);

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var res = new GenericAsyncViewModel();
            res.Start(AsyncConvert(value, targetType, parameter, culture));
            return res;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        private class GenericAsyncViewModel : INotifyPropertyChanged
        {
            private T _result;
            public event PropertyChangedEventHandler PropertyChanged;

            public T Result
            {
                get => _result;
                set
                {
                    _result = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Result)));
                }
            }

            public async void Start(Task<T> task)
            {
                Result = await task;
            }

        }
    }

This is a generic implementation, when we now implement our ImageModelConverter, it looks like that:

 public class ImageModelConverter : AsyncConverter<ImageSource>
    {
        // its a little bit tricky to inject this using IoC, but it's possible
        // but that's not part of this ... so I just create the service here
        public ImageCacheService _imageCacheService = new ImageCacheService();
        public override async Task<ImageSource> AsyncConvert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Models.Image image)
            {
                var imageData = await _imageCacheService.GetImageData(image);
                return ImageSource.FromStream(() => new MemoryStream(imageData));
            }
            return null;
        }
    }

When we use that Converter, it is slightly a little bit different to our usual procedure, we don’t bind the view’s property directly with the converter, but the BindingContext:

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:converters="clr-namespace:AsyncConverter.Converters"
    x:Class="AsyncConverter.MainPage">
 <ContentPage.Resources>
     <converters:ImageModelConverter x:Key="ImageModelConverter"/>
 </ContentPage.Resources>
    <CollectionView ItemsSource="{Binding Products}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Image BindingContext="{Binding Image, Converter={StaticResource ImageModelConverter}}"
                           Source="{Binding Result}" />
                    <Label Grid.Column="1" Text="{Binding Name}" />

                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>


If you are interested in all of the source code, feel free to check it out on git
https://github.com/ThomasKison/AsyncConverter

…feel free to modify and use…I appreciate any feedback.

Flyout in Xamarin forms

Creating a Flyout in Xamarin.Forms

Flyouts are a pretty neat control, first introduced in Windows UWP, but there is nothing close in Xamarin.Forms which can be used on all platforms. So I decided to create one.

What is a Flyout?

from the Windows UWP documentation (https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.flyout?view=winrt-19041)

“Use a Flyout control for collecting information, for displaying more info, or for warnings and confirmations. Unlike a dialog, a Flyout does not create a separate window, and does not block other user interaction.”

So a Flyout can be attached to whatever control you want, and it will pop up as soon as the item is tapped. There are several use cases it easy fits in:
– show more details in a specific context
– ask for confirmation
– ask for more details
– …

How will the XAML look like?

<Label Text="Hello who?">
   <FlyoutBase.AttachedFlyout>
      <Flyout BackgroundColor="Red">
          <Flyout.DataTemplate>
               <DataTemplate>
                  <Label Text="Hello World!"/>
               </DataTemplate>
          </Flyout.DataTemplate>
      </FLyout>
   </FlyoutBase.AttachedFlyout>
</Label>

Looks easy to use, but still needs to be implemented.

Main Challenge: Create a layer over the current content for our Flyout

First we need to add a layer over the whole content of the page, so we can freely place a Flyout on the screen over all other controls. We can achieve that by going up the whole visual tree, find the ContentPage and kinda inject a Grid into it. A Grid is pretty easy to use, and it has the ability to have several Children that arrange in layers one over each other. We need to do this step, because we know nothing about the Layout that is used by the programmer, that created that Page.

FlyoutBase.AttachedFlyout is a AttachedProperty that we can attach to whatever control we need. After the Flyout is attached, we just need to add the TapGesture to that control.

internal class FlyoutRootGrid : Grid {}    // just a specific type, to remind it
public class FlyoutBase
    {
        #region attachedflyout property
        public static readonly BindableProperty AttachedFlyoutProperty =
            BindableProperty.CreateAttached("AttachedFlyout", typeof(Flyout), typeof(FlyoutBase), null, propertyChanged: OnAttachedFlyoutChanged);



        public static Flyout GetAttachedFlyout(BindableObject view)
        {
            return (Flyout)view.GetValue(AttachedFlyoutProperty);
        }

        public static void SetAttachedFlyout(BindableObject view, Flyout value)
        {
            view.SetValue(AttachedFlyoutProperty, value);
        }
        #endregion

        // called whenever a flyout is attached to a view
        private static async void OnAttachedFlyoutChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (bindable is View view)
            {
                await Task.Delay(1000); // we wait a little, so the view is attached to the visual tree
                // this is very weak, we need to think about a better solution here
                AttachFlyout(view);
            }
        }



        private static void AttachFlyout(View view)
        {
            // find the FlyoutRoot
            var flyoutRootGrid = CreateOrFindRootGrid(view);
            // and now attach the flyout to it as child
            var flyout = AttachFlyoutToRoot(flyoutRootGrid, view);
            // register the desture to the visual
            view.GestureRecognizers.Add(
                new TapGestureRecognizer
                {
                    NumberOfTapsRequired = 1,
                    Command = new Command(obj => ToggleFlyoutIsVisible(flyout, view))
                });
        }

        // will go through the visual tree up to the content page
        // remove the content
        // add a "FlyotRootGrid"
        // and set the removed content to it as first child
        private static FlyoutRootGrid CreateOrFindRootGrid(VisualElement view)
        {
            var flyOutRootGrid = VisualTreeHelper.FindParentElement<FlyoutRootGrid>(view);
            // maybe we already have such a control in the visual tree (perhaps we use more than one flyout)
            // so we can reuse it
            if (flyOutRootGrid == null)
            {
                // otherwise attach iot to root
                var parentPage = VisualTreeHelper.FindParentPage<ContentPage>(view);
                flyOutRootGrid = new FlyoutRootGrid();
                var oldContent = parentPage.Content;
                parentPage.Content = flyOutRootGrid;
                flyOutRootGrid.Children.Add(oldContent);
            }
            return flyOutRootGrid;
        }

        private static Flyout AttachFlyoutToRoot(FlyoutRootGrid flyoutRootGrid, View view)
        {
            // get the flyout from the attached property
            var flyout = GetAttachedFlyout(view);
            // not visible yet
            flyout.IsVisible = false;
            // add it to the root grid
            flyoutRootGrid.Children.Add(flyout);
            return flyout;
        }

        private static void ToggleFlyoutIsVisible(Flyout flyout, View view)
        {
            // align flout to the view that has been clicked
            // set IsVisible to the flyout
        }

    }

Now that the Flyout is added to the VisualTree of the ContentPage, we just need to handle the fade in and out of the Flyout. We also have to take care of placing the Flyout correctly on the screen. Therefore we need to find the screen coordinates of the tapped view and position the Flyout accordingly.

private static void ToggleFlyoutIsVisible(Flyout flyout, View view)
{
    bool setVisible = !flyout.IsVisible; // checkout the flyout is visible
    if (flyout.Content == null &amp;&amp; flyout.DataTemplate != null)
    { // when we yet have no content -> create it from datatemplate
        flyout.Content = flyout.DataTemplate.CreateContent() as View;
    }
    if (setVisible)
    {
        flyout.AlignFlyout(view);
    }
    flyout.PlayAnimation(setVisible, view);
}

I don’t just want to set the IsVisible property. Let’s do something fancy and add an animation. But first we need to find the coordinates of the tapped control. I found a solution here (https://forums.xamarin.com/discussion/66386/how-to-get-the-coordinates-where-there-is-a-control-on-the-screen) and adjusted it a little to fit my needs. The VisualTreeHelper also includes the FindParentPage-method from a previous blog post.

public static class VisualTreeHelper
    {
        public static T FindParentPage<T>(Element view)
            where T:Page
        {
            return FindParentElement<T>(view);
        }

        public static T FindParentElement<T>(Element view, Func<T,bool> predicate = null)
            where T:Element
        {
           
            if (view is T element)
            {
                if (predicate == null)
                {
                    return element;
                }
                if (predicate(element))
                {
                    return element;
                }
            }
            if (view.Parent == null)
            {
                return null;
            }
            return FindParentElement<T>(view.Parent, predicate);
        }

        public static (double X, double Y) GetScreenCoordinates(this VisualElement view)
        {
            // A view's default X- and Y-coordinates are LOCAL with respect to the boundaries of its parent,
            // and NOT with respect to the screen. This method calculates the SCREEN coordinates of a view.
            // The coordinates returned refer to the top left corner of the view.
            var screenCoordinateX = view.X;
            var screenCoordinateY = view.Y;

            var parent = (VisualElement)view.Parent;
            while (parent != null &amp;&amp; parent is VisualElement)
            {
                screenCoordinateX += parent.X;
                screenCoordinateY += parent.Y;
                parent = parent.Parent as VisualElement;
            }
            return (screenCoordinateX, screenCoordinateY);
        }
    }

Now we can put all together and implement the Flyout

public class Flyout : ContentView
    {
        public enum AnimationType { Fade, SlideVertical }
        public Flyout()
        {
            HorizontalOptions = LayoutOptions.Start;
            VerticalOptions = LayoutOptions.Start;
        }

        public AnimationType Animation { get; set; }

        public DataTemplate DataTemplate { get; set; }


        double _targetHeight = -1;
        internal async void PlayAnimation(bool setVisible, View view)
        {
            switch (Animation)
            {
                case AnimationType.Fade:
                    if (setVisible)
                    {
                        Opacity = 0;
                        IsVisible = true;
                        await this.FadeTo(1, 250);
                    }
                    else
                    {
                        await this.FadeTo(0, 250);
                        IsVisible = false;
                    }
                    break;
                case AnimationType.SlideVertical:
                    if (setVisible)
                    {
                        if (_targetHeight == -1)
                        {
                            _targetHeight = Height == -1 ? HeightRequest : Height;
                        }
                        HeightRequest = 0;
                        Content.Opacity = 0;

                        IsVisible = true;
                        var animation = new Animation(d => HeightRequest = d, 0, _targetHeight);
                        animation.Commit(this, "Flyout");
                        await Task.Delay(100);
                        await Content.FadeTo(1, 55);

                    }
                    else
                    {
                        await Content.FadeTo(0, 55);
                        var animation = new Animation(d => HeightRequest = d, Height, 0);
                        animation.Commit(this, "Flyout2");
                        await Task.Delay(250);
                        IsVisible = false;
                    }
                    break;
            }
        }

        internal void AlignFlyout(View view)
        {
            var coords = view.GetScreenCoordinates();
            Margin = new Thickness(coords.X, coords.Y + view.Height, 0, 0);
        }

    }

As always you can use and extend the code, however you like. It’s not complete yet, feel free to fix bugs or extend it.

How to find the root Page of a specific Control in Xamarin.Forms

Actually it’s very easy to achieve this. Just traverse the visual tree upwards to find the root.

 public static class VisualTreeHelper
    {
        public static ContentPage FindParentPage(Element view)
        {
            if (view is ContentPage page)
            {
                return page;
            }
            return FindParentPage(view.Parent);
        }
    }

This does what we intended to do, but… we can do better than that!
Maybe we don’t want to just find the (Content)Page, how about finding the root grid, or a parent of a specific type. We just need to take that function and convert it to a generic function, that’s all, and we are way more flexible.

public static class VisualTreeHelper
    {
        public static T FindParentPage<T>(Element view)
            where T:Page
        {
            return FindParentElement<T>(view);
        }

        public static T FindParentElement<T>(Element view)
            where T:Element
        {
           
            if (view is T page)
            {
                return page;
            }
            if (view.Parent == null)
            {
                return null;
            }
            return FindParentElement<T>(view.Parent);
        }
    }

Supported Linq query expressions in Realm

Sooner or later, you’ll come to the point, that you don’t only want to get objects by Id or the whole set of objects of a specific type in Realm. The easiest, but probably most unsophisticated way to do it, would be just use a function on a Linq-Where statement. That’s easy and has reasonable performance, no need to iterate and implement it yourself. But it actually is a big waste of resources, because depending upon the function, every single element needs to be evaluated.

But there is a better way to do so, eventhough it’s support in Realm is very confined. You can use Linq-Expressions. In the next table you find a plan, on what is supported or not:

ExpressionExampleRealmInfo
Int-Query
Double-Query
String-Query
class.Number==4
class.Number>3.4
class.Number<=2
class.Text==”Hello World”
String-Functions:
Contains, StartsWith, EndsWith
class.Text.StartsWith(“T”)as StringComparison you can use Ordinal or OrdinalIgnoreCase
advanced calculationclass.Number*20>100no left-side operations are supported, but right-side operations
Same-Object Comparisonclass.Number>class.Number2only comparison with constant values are supported
List-Functionsclass.List.Contains(3)
Sub-Object-Accessclass.SubClass.Number==1
Take()Take(20)
Skip()Skip(5)

That’s really not a lot. Actually it ends up with numeric type comparisons (==,<,>..) and some string-Comparer (==,Contains, StartsWith, EndsWith). I really hope Mongo Inc. will spend some more time on implementing more Linq-Expression features in Realm.

But actually there is a (little) work around (which I didn’t yet check out in terms of performance). You can use the Filter-function, which takes a query that is inspired by NSPredicate. (you can find more details here)

ExpressionFilter
advanced calculation
Same-Object ComparisonSubClass.Number>Number
List-FunctionsANY SubClassArray.Number>10
ANY or SOME works only with RealmObject-Arrays, not with atomic type arrays
Sub-Object-AccessSubClass.Number>20
Take()
Skip()

Summarizing my investigation and research on this, I can say: There’s space for improvement. I am very keen on finding out, whether MongoRealm will have a more sufficient way to query data.

User Access Management in Realm

As I already stated before, I love Realm.io. It’s a pretty cool object oriented database, with a very mighty synchronization mechanism, that helps you build mobile apps just right out of the box. But that’s not the end of the line.. It also ships with a very mighty user management feature.

When you develop mobile apps, you sooner or later want users to get authenticated. You need a user management, with registration, authentication, and permission management. That’s all but easy.

Realm delivers all of it, with some easy steps.

  1. User registration
    var usr = await User.LoginAsync(Credentials.UsernamePassword("Tom", "test", true), new Uri("realmUrl"));
    // an exception will be thrown, when the user already exists
  2. User login
    var usr = await User.LoginAsync(Credentials.UsernamePassword("Tom", "test", false), new Uri("realmUrl"));

Now that you have a user registered and logged in, you can create as many realms as you like. But you can only create realms with your UserId, in most cases this is not the Username. But don’t panic, you don’t need to store it somewhere. When you open a Realm, just add a Tilde, which will automatically get replaced with your UserId.

FullSyncConfiguration conf = new FullSyncConfiguration(new Uri("~/MyLittleRealm", UriKind.Relative));
var realm = Realm.GetInstance(conf);

Pretty easy, isn’t it? But that’s not all. Let’s assume we have an App to manage your shopping list. That’s probably enough, but you also want to share your shopping list with your wife or kids. Everyone using your App will actually have it’s own list, but can’t access the others. But you know what realms they are using, so you could synchronize them too, perhaps it is something like <UserId>/ShoppingList . But first of all you don’t have their UserId (this is not the username!) and also no permission to access it. A user needs to actively grant someone else access to their Realms:

await User.Current.ApplyPermissionsAsync(PermissionCondition.UserId("someonesUserId"), "~/ShoppingList", AccessLevel.Read | AccessLevel.Write);

You can even choose if the user can read or read and write your Realm. But how do we get the UserId?

There are two approaches to that challenge:

  1. you can store the UserId in a public realm, this is okay, but not a very secure solution
  2. your App can offer a way to directly send the UserId to others using WhatsApp, NFC or a QR-Code .. that is easy and everyone has complete control to their data (even though it’s only an ID)
  3. Didn’t I just talk about two? Ok, I think there are probably more than that, there could be something like “Sync”-Mode.. a User can write an offer in a public realm, stating he wants to share his shopping list with a user with username “xy”, the App of user “xy” could react upon that offer and publish its UserId.

By the way: When you are using an external Authentication (like an Identity-Server or similar) that offers a JWT-Token, the UserId will be the same as the Username.

Using Realm Notifications in .Net

There is a documentation on Realm.io, that describes how to hook up on a ROS (Realm Object Server) to observe changes on specific Realms, RealmObjects or whole instances. So there is no need to actually download the whole Realm, since it “sees” the changes directly on the server. It is also pretty cool, that you don’t have to load the assemblies that contain the correct RealmObjects (and version), because it uses the .Net DynamicObject feature.

https://docs.realm.io/sync/backend-integration/data-change-events#integrating-with-a-3rd-party-api

Sadly, this only works with node.js not in .Net…

There is currently only one work around, that really works with .Net Standard, that I have found. You open the specific Realm in dynamic mode and use the method SubscribeForNotifications. Be sure to have a separate Thread running for the notifications to work properly.

static async Task Main(string[] args)
{
var adminUser = await User.LoginAsync(Credentials.UsernamePassword("aUser", "****", false), new Uri("https://rosurl"));
var realmSyncConfig = new Realms.Sync.FullSyncConfiguration(
new Uri("SomeRealm", UriKind.Relative), adminUser);
realmSyncConfig.IsDynamic = true;
Nito.AsyncEx.AsyncContext.Run(async () =&gt;
{
var realm = await Realm.GetInstanceAsync(realmSyncConfig);
var realmCollection = realm.All("Organization") as RealmCollectionBase&lt;RealmObject&gt;;
var token = realmCollection.SubscribeForNotifications(RealmChanged);

while (true)
{
// you can use a cancellation token here
await Task.Delay(1000);
}
token.Dispose();
realm.Dispose();
});
Console.ReadLine();
}

private static void RealmChanged(IRealmCollection&lt;RealmObject&gt; sender, ChangeSet changes, Exception error)
{
/* here you can handle changes */
}

There are some disadvantages when you use this solution:
1. The Realm that you want to subscribe changes on will be fully synced. (So it’s not a good solution for very large Realms)
2. You can’t just watch your whole instance, you need to actually know the full name of your Realm

Performance of loading Xaml dynamically in Xamarin.Forms

As I mentioned in a previous post, you can quite easily load Xaml dynamically in your Xamarin.Forms App. But how about performance? How long does it take in comparison to “regular” loading of pre-compiled Xaml.

It’s anything but easy to really measure this. We could eventually use LoadFromXaml and measure the differences. I decided to create DataTemplates and use the CreateContent() method to create the actual Control.

&lt;DataTemplate x:Key=&quot;Test1&quot;&gt;
&lt;Grid&gt;
    &lt;Grid.RowDefinitions&gt;
        &lt;RowDefinition Height=&quot;auto&quot; /&gt;
        &lt;RowDefinition Height=&quot;*&quot; /&gt;

    &lt;/Grid.RowDefinitions&gt;
    &lt;Label Text=&quot;Hello World!&quot; /&gt;
    &lt;Button Grid.Row=&quot;1&quot; Text=&quot;Press me&quot; /&gt;
&lt;/Grid&gt;
&lt;/DataTemplate&gt;
&lt;DataTemplate x:Key=&quot;Test2&quot;&gt;
    &lt;dynamiccontrol:XamlView&gt;
        &lt;dynamiccontrol:XamlView.Xaml&gt;
            &lt;![CDATA[
            &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                    &lt;RowDefinition Height=&quot;auto&quot; /&gt;
                    &lt;RowDefinition Height=&quot;*&quot; /&gt;

                &lt;/Grid.RowDefinitions&gt;
                &lt;Label Text=&quot;Hello World!&quot; /&gt;
                &lt;Button Grid.Row=&quot;1&quot; Text=&quot;Press me&quot; /&gt;
            &lt;/Grid&gt;
            ]]&gt;
        &lt;/dynamiccontrol:XamlView.Xaml&gt;
    &lt;/dynamiccontrol:XamlView&gt;
           
&lt;/DataTemplate&gt;

You can see that the Xaml is quite easy, but loading it dynamically takes over 20 times longer than compiled Xaml.

I tried to create 10,000 controls and measured the following values:
Compiled Xaml: 5.8s
Dynamic Xaml: 133.1s

I know the test is not very representative, but you should always keep in mind that there may be a performance problem when using this method. Especially when you want to create dynamic Layouts in ListViews.

You can slightly boost performance (5-10%), when you load the whole DataTemplate from Xaml, and then create the Control with it.

Dynamic DataTemplate: 124s

Never ever use Task.Result in Xamarin.Forms! Why?

I recently stumbled over a deadlock in our code. Someone called a method, that returned a Task, and instead of awaiting it, he called:

var res = Method().Result;

I reason for this code was just plain laziness, because using await requires an async-context, which probably isn’t that easy to achieve. But what’s the reason for that deadlock, and why is awaiting the result actually resolving it?

I don’t want to dick very deeply into the Task Parallel Library (TPL). But let’s just make clear, what a task is. A task is a “unit of execution”, it has no direct link to Threads (even though it’s in the same namespace). A Thread can run tasks, there can be one or more Threads in your program. Let’s assume that Threads run in parallel.

So now let’s make up some setting, we call a method (which returns and starts a Task, that’s what “async Task” does) and then wait for the result by calling “.Result”. That call will actually block the current thread and wait for the second task to finish.

Result is working

When we look at the graphic above, we see that this call is working. We actually block Thread 1, but we have not created a deadlock. But we can never be sure, that the TaskScheduler (it is planning what Tasks runs on which Thread) really runs Task2 on Thread2. As soon as the TaskScheduler decides to run Task2 on Thread1, we have a classic deadlock:

DeadlockTask

But what is the difference to async/await pattern?

A couple of years ago, a friend described async-await pattern as syntactical sugar, it’s not a language feature, nor a real pattern. There is something true to that, but it makes programming Tasks so much easier. It actually splits your code into separate parts, and calls them in a sequence. So there will be no busy wait, no matter which Thread the Task we are waiting for is executed on.

TaskAsyncAwait