• Stars
    star
    1,277
  • Rank 36,858 (Top 0.8 %)
  • Language
    C#
  • License
    MIT License
  • Created almost 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Extensions for System.Threading.Tasks.Task and System.Threading.Tasks.ValueTask

AsyncAwaitBestPractices

Build Status

Extensions for System.Threading.Tasks.Task.

Inspired by John Thiriet's blog posts:

AsyncAwaitBestPractices

NuGet

Available on NuGet: https://www.nuget.org/packages/AsyncAwaitBestPractices/

  • SafeFireAndForget
    • An extension method to safely fire-and-forget a Task or a ValueTask
    • Ensures the Task will rethrow an Exception if an Exception is caught in IAsyncStateMachine.MoveNext()
  • WeakEventManager
    • Avoids memory leaks when events are not unsubscribed
    • Used by AsyncCommand, AsyncCommand<T>, AsyncValueCommand, AsyncValueCommand<T>
  • Usage instructions

AsyncAwaitBestPractices.MVVM

NuGet

  • Available on NuGet: https://www.nuget.org/packages/AsyncAwaitBestPractices.MVVM/

  • Allows for Task to safely be used asynchronously with ICommand:

    • IAsyncCommand : ICommand
    • AsyncCommand : IAsyncCommand
    • IAsyncCommand<T> : ICommand
    • AsyncCommand<T> : IAsyncCommand<T>
    • IAsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute>
    • AsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute, TCanExecute>
  • Allows for ValueTask to safely be used asynchronously with ICommand:

    • IAsyncValueCommand : ICommand
    • AsyncValueCommand : IAsyncValueCommand
    • IAsyncValueCommand<T> : ICommand
    • AsyncValueCommand<T> : IAsyncValueCommand<T>
    • IAsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute>
    • AsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute, TCanExecute>
  • Usage instructions

Setup

AsyncAwaitBestPractices

AsyncAwaitBestPractices.MVVM

Why Do I Need This?

Podcasts

No Dogma Podcast, Hosted by Bryan Hogan

Video

NDC Oslo 2019

Correcting Common Async Await Mistakes in .NET

Explaination

Async/await is great but there are two subtle problems that can easily creep into code:

  1. Creating race conditions/concurrent execution (where you code things in the right order but the code executes in a different order than you expect)
  2. Creating methods where the compiler recognizes exceptions but you the coder never see them (making it head-scratchingly annoying to debug especially if you accidentally introduced a race condition that you can’t see).

This library solves both of these problems.

To better understand why this library was created and the problem it solves, it’s important to first understand how the compiler generates code for an async method.

tl;dr A non-awaited Task doesn't rethrow exceptions and AsyncAwaitBestPractices.SafeFireAndForget ensures it will

Compiler-Generated Code for Async Method

Compiler-Generated Code for Async Method

(Source: Xamarin University: Using Async and Await)

The compiler transforms an async method into an IAsyncStateMachine class which allows the .NET Runtime to "remember" what the method has accomplished.

Move Next

(Source: Xamarin University: Using Async and Await)

The IAsyncStateMachine interface implements MoveNext(), a method the executes every time the await operator is used inside of the async method.

MoveNext() essentially runs your code until it reaches an await statement, then it returns while the await'd method executes. This is the mechanism that allows the current method to "pause", yielding its thread execution to another thread/Task.

Try/Catch in MoveNext()

Look closely at MoveNext(); notice that it is wrapped in a try/catch block.

Because the compiler creates IAsyncStateMachine for every async method and MoveNext() is always wrapped in a try/catch, every exception thrown inside of an async method is caught!

How to Rethrow an Exception Caught By MoveNext

Now we see that the async method catches every exception thrown - that is to say, the exception is caught internally by the state machine, but you the coder will not see it. In order for you to see it, you'll need to rethrow the exception to surface it in your debugging. So the questions is - how do I rethrow the exception?

There are a few ways to rethrow exceptions that are thrown in an async method:

  1. Use the await keyword (Prefered)
    • e.g. await DoSomethingAsync()
  2. Use .GetAwaiter().GetResult()
    • e.g. DoSomethingAsync().GetAwaiter().GetResult()

The await keyword is preferred because await allows the Task to run asynchronously on a different thread, and it will not lock-up the current thread.

What About .Result or .Wait()?

Never, never, never, never, never use .Result or .Wait():

  1. Both .Result and .Wait() will lock-up the current thread. If the current thread is the Main Thread (also known as the UI Thread), your UI will freeze until the Task has completed.

  2. .Result or .Wait() rethrow your exception as a System.AggregateException, which makes it difficult to find the actual exception.

Usage

AsyncAwaitBestPractices

SafeFireAndForget

An extension method to safely fire-and-forget a Task.

SafeFireAndForget allows a Task to safely run on a different thread while the calling thread does not wait for its completion.

public static async void SafeFireAndForget(this System.Threading.Tasks.Task task, System.Action<System.Exception>? onException = null, bool continueOnCapturedContext = false)
public static async void SafeFireAndForget(this System.Threading.Tasks.ValueTask task, System.Action<System.Exception>? onException = null, bool continueOnCapturedContext = false)

Basic Usage - Task

void HandleButtonTapped(object sender, EventArgs e)
{
    // Allows the async Task method to safely run on a different thread while the calling thread continues, not awaiting its completion
    // onException: If an Exception is thrown, print it to the Console
    ExampleAsyncMethod().SafeFireAndForget(onException: ex => Console.WriteLine(ex));

    // HandleButtonTapped continues execution here while `ExampleAsyncMethod()` is running on a different thread
    // ...
}

async Task ExampleAsyncMethod()
{
    await Task.Delay(1000);
}

Basic Usage - ValueTask

If you're new to ValueTask, check out this great write-up, Understanding the Whys, Whats, and Whens of ValueTask .

void HandleButtonTapped(object sender, EventArgs e)
{
    // Allows the async ValueTask method to safely run on a different thread while the calling thread continues, not awaiting its completion
    // onException: If an Exception is thrown, print it to the Console
    ExampleValueTaskMethod().SafeFireAndForget(onException: ex => Console.WriteLine(ex));

    // HandleButtonTapped continues execution here while `ExampleAsyncMethod()` is running on a different thread
    // ...
}

async ValueTask ExampleValueTaskMethod()
{
    var random = new Random();
    if (random.Next(10) > 9)
        await Task.Delay(1000);
}

Advanced Usage

void InitializeSafeFireAndForget()
{
    // Initialize SafeFireAndForget
    // Only use `shouldAlwaysRethrowException: true` when you want `.SafeFireAndForget()` to always rethrow every exception. This is not recommended, because there is no way to catch an Exception rethrown by `SafeFireAndForget()`; `shouldAlwaysRethrowException: true` should **not** be used in Production/Release builds.
    SafeFireAndForgetExtensions.Initialize(shouldAlwaysRethrowException: false);

    // SafeFireAndForget will print every exception to the Console
    SafeFireAndForgetExtensions.SetDefaultExceptionHandling(ex => Console.WriteLine(ex));
}

void UninitializeSafeFireAndForget()
{
    // Remove default exception handling
    SafeFireAndForgetExtensions.RemoveDefaultExceptionHandling();
}

void HandleButtonTapped(object sender, EventArgs e)
{
    // Allows the async Task method to safely run on a different thread while not awaiting its completion
    // onException: If a WebException is thrown, print its StatusCode to the Console. **Note**: If a non-WebException is thrown, it will not be handled by `onException`
    // Because we set `SetDefaultExceptionHandling` in `void InitializeSafeFireAndForget()`, the entire exception will also be printed to the Console
    ExampleAsyncMethod().SafeFireAndForget<WebException>(onException: ex =>
    {
        if(ex.Response is HttpWebResponse webResponse)
            Console.WriteLine($"Task Exception\n Status Code: {webResponse.StatusCode}");
    });
    
    ExampleValueTaskMethod().SafeFireAndForget<WebException>(onException: ex =>
    {
        if(ex.Response is HttpWebResponse webResponse)
            Console.WriteLine($"ValueTask Error\n Status Code: {webResponse.StatusCode}");
    });

    // HandleButtonTapped continues execution here while `ExampleAsyncMethod()` and `ExampleValueTaskMethod()` run in the background
}

async Task ExampleAsyncMethod()
{
    await Task.Delay(1000);
    throw new WebException();
}

async ValueTask ExampleValueTaskMethod()
{
    var random = new Random();
    if (random.Next(10) > 9)
        await Task.Delay(1000);
        
    throw new WebException();
}

WeakEventManager

An event implementation that enables the garbage collector to collect an object without needing to unsubscribe event handlers.

Inspired by Xamarin.Forms.WeakEventManager.

Using EventHandler

readonly WeakEventManager _canExecuteChangedEventManager = new WeakEventManager();

public event EventHandler CanExecuteChanged
{
    add => _canExecuteChangedEventManager.AddEventHandler(value);
    remove => _canExecuteChangedEventManager.RemoveEventHandler(value);
}

void OnCanExecuteChanged() => _canExecuteChangedEventManager.RaiseEvent(this, EventArgs.Empty, nameof(CanExecuteChanged));

Using Delegate

readonly WeakEventManager _propertyChangedEventManager = new WeakEventManager();

public event PropertyChangedEventHandler PropertyChanged
{
    add => _propertyChangedEventManager.AddEventHandler(value);
    remove => _propertyChangedEventManager.RemoveEventHandler(value);
}

void OnPropertyChanged([CallerMemberName]string propertyName = "") => _propertyChangedEventManager.RaiseEvent(this, new PropertyChangedEventArgs(propertyName), nameof(PropertyChanged));

Using Action

readonly WeakEventManager _weakActionEventManager = new WeakEventManager();

public event Action ActionEvent
{
    add => _weakActionEventManager.AddEventHandler(value);
    remove => _weakActionEventManager.RemoveEventHandler(value);
}

void OnActionEvent(string message) => _weakActionEventManager.RaiseEvent(message, nameof(ActionEvent));

WeakEventManager<T>

An event implementation that enables the garbage collector to collect an object without needing to unsubscribe event handlers.

Inspired by Xamarin.Forms.WeakEventManager.

Using EventHandler<T>

readonly WeakEventManager<string> _errorOcurredEventManager = new WeakEventManager<string>();

public event EventHandler<string> ErrorOcurred
{
    add => _errorOcurredEventManager.AddEventHandler(value);
    remove => _errorOcurredEventManager.RemoveEventHandler(value);
}

void OnErrorOcurred(string message) => _errorOcurredEventManager.RaiseEvent(this, message, nameof(ErrorOcurred));

Using Action<T>

readonly WeakEventManager<string> _weakActionEventManager = new WeakEventManager<string>();

public event Action<string> ActionEvent
{
    add => _weakActionEventManager.AddEventHandler(value);
    remove => _weakActionEventManager.RemoveEventHandler(value);
}

void OnActionEvent(string message) => _weakActionEventManager.RaiseEvent(message, nameof(ActionEvent));

AsyncAwaitBestPractices.MVVM

AsyncCommand

Allows for Task to safely be used asynchronously with ICommand:

  • AsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute, TCanExecute>
  • IAsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute>
  • AsyncCommand<T> : IAsyncCommand<T>
  • IAsyncCommand<T> : ICommand
  • AsyncCommand : IAsyncCommand
  • IAsyncCommand : ICommand
public AsyncCommand(Func<TExecute, Task> execute,
                     Func<TCanExecute, bool>? canExecute = null,
                     Action<Exception>? onException = null,
                     bool continueOnCapturedContext = false)
public AsyncCommand(Func<T, Task> execute,
                     Func<object?, bool>? canExecute = null,
                     Action<Exception>? onException = null,
                     bool continueOnCapturedContext = false)
public AsyncCommand(Func<Task> execute,
                     Func<object?, bool>? canExecute = null,
                     Action<Exception>? onException = null,
                     bool continueOnCapturedContext = false)
public class ExampleClass
{
    bool _isBusy;

    public ExampleClass()
    {
        ExampleAsyncCommand = new AsyncCommand(ExampleAsyncMethod);
        ExampleAsyncIntCommand = new AsyncCommand<int>(ExampleAsyncMethodWithIntParameter);
        ExampleAsyncIntCommandWithCanExecute = new AsyncCommand<int, int>(ExampleAsyncMethodWithIntParameter, CanExecuteInt);
        ExampleAsyncExceptionCommand = new AsyncCommand(ExampleAsyncMethodWithException, onException: ex => Console.WriteLine(ex.ToString()));
        ExampleAsyncCommandWithCanExecuteChanged = new AsyncCommand(ExampleAsyncMethod, _ => !IsBusy);
        ExampleAsyncCommandReturningToTheCallingThread = new AsyncCommand(ExampleAsyncMethod, continueOnCapturedContext: true);
    }

    public IAsyncCommand ExampleAsyncCommand { get; }
    public IAsyncCommand<int> ExampleAsyncIntCommand { get; }
    public IAsyncCommand<int, int> ExampleAsyncIntCommandWithCanExecute { get; }
    public IAsyncCommand ExampleAsyncExceptionCommand { get; }
    public IAsyncCommand ExampleAsyncCommandWithCanExecuteChanged { get; }
    public IAsyncCommand ExampleAsyncCommandReturningToTheCallingThread { get; }
    
    public bool IsBusy
    {
        get => _isBusy;
        set
        {
            if (_isBusy != value)
            {
                _isBusy = value;
                ExampleAsyncCommandWithCanExecuteChanged.RaiseCanExecuteChanged();
            }
        }
    }

    async Task ExampleAsyncMethod()
    {
        await Task.Delay(1000);
    }
  
    async Task ExampleAsyncMethodWithIntParameter(int parameter)
    {
        await Task.Delay(parameter);
    }

    async Task ExampleAsyncMethodWithException()
    {
        await Task.Delay(1000);
        throw new Exception();
    }

    bool CanExecuteInt(int count)
    {
        if(count > 2)
            return true;
        
        return false;
    }

    void ExecuteCommands()
    {
        _isBusy = true;
    
        try
        {
            ExampleAsyncCommand.Execute(null);
            ExampleAsyncIntCommand.Execute(1000);
            ExampleAsyncExceptionCommand.Execute(null);
            ExampleAsyncCommandReturningToTheCallingThread.Execute(null);
            
            if(ExampleAsyncCommandWithCanExecuteChanged.CanExecute(null))
                ExampleAsyncCommandWithCanExecuteChanged.Execute(null);
            
            if(ExampleAsyncIntCommandWithCanExecute.CanExecute(1))
                ExampleAsyncIntCommandWithCanExecute.Execute(1);
        }
        finally
        {
            _isBusy = false;
        }
    }
}

AsyncValueCommand

Allows for ValueTask to safely be used asynchronously with ICommand.

If you're new to ValueTask, check out this great write-up, Understanding the Whys, Whats, and Whens of ValueTask .

  • AsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute, TCanExecute>
  • IAsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute>
  • AsyncValueCommand<T> : IAsyncValueCommand<T>
  • IAsyncValueCommand<T> : ICommand
  • AsyncValueCommand : IAsyncValueCommand
  • IAsyncValueCommand : ICommand
public AsyncValueCommand(Func<TExecute, ValueTask> execute,
                            Func<TCanExecute, bool>? canExecute = null,
                            Action<Exception>? onException = null,
                            bool continueOnCapturedContext = false)
public AsyncValueCommand(Func<T, ValueTask> execute,
                            Func<object?, bool>? canExecute = null,
                            Action<Exception>? onException = null,
                            bool continueOnCapturedContext = false)
public AsyncValueCommand(Func<ValueTask> execute,
                            Func<object?, bool>? canExecute = null,
                            Action<Exception>? onException = null,
                            bool continueOnCapturedContext = false)
public class ExampleClass
{
    bool _isBusy;

    public ExampleClass()
    {
        ExampleValueTaskCommand = new AsyncValueCommand(ExampleValueTaskMethod);
        ExampleValueTaskIntCommand = new AsyncValueCommand<int>(ExampleValueTaskMethodWithIntParameter);
        ExampleValueTaskIntCommandWithCanExecute = new AsyncValueCommand<int, int>(ExampleValueTaskMethodWithIntParameter, CanExecuteInt);
        ExampleValueTaskExceptionCommand = new AsyncValueCommand(ExampleValueTaskMethodWithException, onException: ex => Debug.WriteLine(ex.ToString()));
        ExampleValueTaskCommandWithCanExecuteChanged = new AsyncValueCommand(ExampleValueTaskMethod, _ => !IsBusy);
        ExampleValueTaskCommandReturningToTheCallingThread = new AsyncValueCommand(ExampleValueTaskMethod, continueOnCapturedContext: true);
    }

    public IAsyncValueCommand ExampleValueTaskCommand { get; }
    public IAsyncValueCommand<int> ExampleValueTaskIntCommand { get; }
    public IAsyncCommand<int, int> ExampleValueTaskIntCommandWithCanExecute { get; }
    public IAsyncValueCommand ExampleValueTaskExceptionCommand { get; }
    public IAsyncValueCommand ExampleValueTaskCommandWithCanExecuteChanged { get; }
    public IAsyncValueCommand ExampleValueTaskCommandReturningToTheCallingThread { get; }

    public bool IsBusy
    {
        get => _isBusy;
        set
        {
            if (_isBusy != value)
            {
                _isBusy = value;
                ExampleValueTaskCommandWithCanExecuteChanged.RaiseCanExecuteChanged();
            }
        }
    }

    async ValueTask ExampleValueTaskMethod()
    {
        var random = new Random();
        if (random.Next(10) > 9)
            await Task.Delay(1000);
    }

    async ValueTask ExampleValueTaskMethodWithIntParameter(int parameter)
    {
        var random = new Random();
        if (random.Next(10) > 9)
            await Task.Delay(parameter);
    }

    async ValueTask ExampleValueTaskMethodWithException()
    {
        var random = new Random();
        if (random.Next(10) > 9)
            await Task.Delay(1000);

        throw new Exception();
    }

    bool CanExecuteInt(int count)
    {
        if(count > 2)
            return true;
        
        return false;
    }

    void ExecuteCommands()
    {
        _isBusy = true;

        try
        {
            ExampleValueTaskCommand.Execute(null);
            ExampleValueTaskIntCommand.Execute(1000);
            ExampleValueTaskExceptionCommand.Execute(null);
            ExampleValueTaskCommandReturningToTheCallingThread.Execute(null);

            if (ExampleValueTaskCommandWithCanExecuteChanged.CanExecute(null))
                ExampleValueTaskCommandWithCanExecuteChanged.Execute(null);

            if(ExampleValueTaskIntCommandWithCanExecute.CanExecute(2))
                ExampleValueTaskIntCommandWithCanExecute.Execute(2);
        }
        finally
        {
            _isBusy = false;
        }
    }
}

Learn More

More Repositories

1

GitTrends

A iOS and Android app to monitor the Views, Clones and Star history of your GitHub repos
C#
723
star
2

HackerNews

A .NET MAUI app for displaying the top posts on Hacker News that demonstrates text sentiment analysis gathered using artificial intelligence
C#
210
star
3

ImproveXamarinBuildTimes

Tips and tricks on how to speed up the time it takes to compile a Xamarin app
176
star
4

FaceOff

An iOS, Android and UWP app created in Xamarin.Forms that uses Microsoft's Cognitive Emotion API Services to compare facial expressions
C#
90
star
5

EntryCustomReturnPlugin

Xamarin.Forms Plugin to customize the Xamarin.Forms.Entry Keyboard Return Button
C#
81
star
6

DotNetGraphQL

A sample demonstrating how to create a GraphQL Backend in .NET using `GraphQL-Dotnet` and consume it from a .NET mobile app created using Xamarin
JavaScript
79
star
7

InvestmentDataSampleApp

This app utilizes a SQLite databse, MVVM, along with these Xamarin.Forms controls: Search Bar, Picker, Grid, StackLayout, Navigation Page, ListView, ViewCell. It also shows how to tweak the UI to best appear on larger tablet screens.
C#
57
star
8

FacialRecognitionLogin

An iOS and Android app that uses facial recognition to enhance the security of a login page. Built using Xamarin.Forms and Microsoft Cognitive Services.
C#
57
star
9

TextMood

A Xamarin + IoT + Azure sample that detects the sentiment of incoming text messages, performs sentiment analysis on the text, and changes the color of a Philips Hue lightbulb
C#
52
star
10

XamList

An iOS and Android app showcasing Azure Functions, Xamarin.Forms, Azure SQL Database and Azure API Apps
C#
47
star
11

azure-for-developers-workshop

The Azure cloud is huge and the vast service catalog may appear daunting at first, but it doesn’t have to be!
C#
47
star
12

UITestSampleApp

A sample app to demonstrate how to create Xamarin UITests using the Page Object architecture, Backdoor Methods and App Links (aka Deep Linking)
C#
39
star
13

DarkModeSplashScreen

A sample app for iOS and Android written in Xamarin.Forms showing how to implement a Splash Page for Dark Mode
C#
33
star
14

AzureBlobStorageSampleApp

iOS and Android app made using Xamarin.Forms that explores Azure Blob Storage
C#
29
star
15

csharp-workshop

NDC London 2019, Workshop: Become a better C# programmer: more Value, more Expressions, no Waiting
C#
22
star
16

SimpleXamarinGraphQL

An iOS and Android app built in Xamarin.Forms demonstrating how to interact with GitHub's GraphQL API
C#
20
star
17

HotChocolateGraphQL

A sample demonstrating how to create a GraphQL Backend in .NET using HotChocolate and consume it from a .NET mobile app created using .NET MAUI + Strawberry Shake
C#
20
star
18

HelloMauiMarkup

An iOS, Android, macOS + Windows app built using .NET MAUI, demonstrating how to use the .NET MAUI Markup Community Toolkit
C#
20
star
19

LocalNotificationsSample

A sample iOS and Android app demonstrating Shiny.Notifications in Xamarin.Forms
C#
17
star
20

HelloMauiToolkit

An iOS, Android, macOS + Windows app built using .NET MAUI, demonstrating how to use the .NET MAUI CommunityToolkit
C#
17
star
21

SaveImageToDatabaseSampleApp

A iOS and Android app that demonstrates how to download an image from a url and save it to a SQLite database
C#
16
star
22

MauiConverter

An iOS and Android app created in .NET MAUI using an MVVM architecture that converts units of Length, Mass and Temperature.
C#
16
star
23

GitHubApiStatus

A .NET library to easily parse GitHub's API Rate Limit
C#
16
star
24

CosmosDbSampleApp

A Xamarin.iOS and Xamarin.Android app built using Xamarin.Forms that utilizes a Cosmos DB Azure Backend
C#
15
star
25

GitHubXamarin

This repository has moved: https://github.com/brminnick/gittrends
C#
15
star
26

GitHubReadmeWebTrends

An automated tool created using Azure Functions that double checks each Readme to ensure every repository is leveraging Web Trends
C#
15
star
27

XamarinIoTWorkshop

A workshop that demonstrates how to collect IoT data from a mobile device using a Xamarin app, aggregating the data to the cloud using Azure IoT Hub
C#
13
star
28

AsyncCommandSample

An iOS + Android app built in Xamarin.Forms demonstrating Xamarin.CommunityToolkit AsyncCommand
C#
12
star
29

SimpleCSharpMarkup

A Xamarin.Forms app demonstrating C# Markup
C#
12
star
30

HealthClinic

An iOS & Android app built in Xamarin.Forms that parses images of food to give nutritional information. Leverages Azure's Cognitive Services.
C#
11
star
31

LambdaTriggersSample

A sample app demonstrating an end-to-end mobile workflow using .NET MAUI, + Serverless AWS Lambda + AWS S3 Storage in C#
C#
11
star
32

AzureMediaServicesSampleApp

An iOS and Android app made in Xamarin.Forms that integrates with Azure Media Services
C#
10
star
33

XamarinBlobStorageApp

A a single-page Xamarin.Forms app that displays an image from Azure Blob Storage by communicating directly with an Azure Blob Storage Container using the Azure Storage SDK for .NET.
C#
10
star
34

GitHubExplorer

C# Console App to explore the GitHub GraphQL API
C#
10
star
35

GeolocatorSample

iOS and Android app that gathers Geolocation data; created in Xamarin.Forms
C#
9
star
36

AccelerometerApp

An iOS and Android app that tracks the device's accelerometer using Xamarin.Essentials; created using Xamarin.Forms and Syncfusion
C#
9
star
37

XamSpeak

An iOS and Android app that will dictate text from a photo. XamSpeak leverages Microsoft Cognitive Services to perform Optical Character Recognition (OCR) and Spell Check.
C#
9
star
38

SecuritySampleApp

This app is a Xamarin.Forms app that uses the Xamarin Settings Plugin, MVVM and the following Xamarin.Forms controls: Slider, TableView, ListView, Carousel Page, Navigation Page
C#
9
star
39

AppCenterAuthDataSample

A sample app demonstrating App Center Auth and App Center Data, built for iOS and Android using Xamarin.Forms
C#
8
star
40

PowerBISampleApp

Sample App demonstrating how to integrate Power BI with Xamarin.Forms
C#
7
star
41

CustomStepper

Sample app showing how to set the color of a Xamarin.Forms.Stepper using effects and custom renderers
C#
7
star
42

ExpandableList

A Xamarin.iOS and Xamarin.Android app demonstrating how to create an Expandable List
C#
7
star
43

EntryUITest

A very simple Xamarin.Forms app that contains a basic UITest
C#
6
star
44

OnSight

Xamarin.Forms app for field inspections
C#
6
star
45

XamMedia

Xamarin.iOS and Xamarin.Android app to display meida from YouTube and Vimeo
C#
5
star
46

MauiSentryApp

A .NET MAUI App demonstrating how to use the Sentry Crashes + Analytics SDK
C#
5
star
47

24HourTimePicker

A 24 Hour Time Picker for Xamarin.Forms
C#
4
star
48

SimpleUITestApp

This repo has moved
4
star
49

XamarinSentryApp

A iOS + Android sample app that demonstrates how to use Sentry's RavenClient with Xamarin
C#
4
star
50

MasterDetailTabbedSearchBar

Sample app demonstrating how to add a SearchBar to a NavigationPage inside of a TabbedPage inside of a MasterDetailPage
C#
4
star
51

HelloMauiToolkits

A .NET MAUI sample created to demonstrate the power of `CommunityToolkit.Mvvm`, `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Markup`
C#
4
star
52

CreatingTaskFromScratch

A learning repository where we use a custom implementation of Task in a .NET MAUI app
C#
4
star
53

WebViewUITestApp

C#
3
star
54

ReactNativeSampleApp

Demonstration of how to write a Xamarin.UITest for an iOS app built using React Native
Objective-C
3
star
55

MultipleViewModelSample

An iOS and Anrdoid app built using Xamarin.Forms demonstrating how to have multiple views reference two different ViewModels from the same ContentPage
C#
3
star
56

AutoCompleteSample

An iOS and Android app built in Xamarin.Forms, demontstrating the Syncfusion Autocomplete control
C#
3
star
57

StrawberryMaui

A sample app using an AWS AppSync backend demonstrating how to consume GraphQL in a .NET MAUI app
C#
3
star
58

SentimentAnalysis

An iOS and Android app made using Xamarin.Forms that uses Azure's Sentiment Analysis API to determine the sentiment of a message
C#
3
star
59

ICommandAttribute_NullableParameter_Repro

A reproduction sample for CommunityToolkit.Command
C#
2
star
60

MissingEmptyViewRepro

A reproduction sample for Xamarin.Forms v5.0.0.1487-pre1, where the `CollectionView.EmptyView` no longer appears on iOS
C#
2
star
61

CollectionViewBoundsExceptionRepro

Reproduction Sample for Xamarin.Forms.CollectionView
C#
2
star
62

PancakeViewRepro

A reproduction sample demonstrating a regression in Xamarin.Forms.PancakeView v2.3.0.752-beta
C#
2
star
63

LayoutChildAddedRepro

A .NET MAUI reproduction sample for `Layout.ChildAdded`
C#
2
star
64

Videos

Repository to hold videos
2
star
65

DynamicStackLayoutSize

A sample app written in Xamarin.Forms that shows how to dynamically change the height of a Xamarin.Forms.StackLayout
C#
2
star
66

RedditStats

A web API to retrieve Reddit user statistics
C#
2
star
67

Xcode_XamarinUITest_SampleApp

This sample app demonstrates how to add Xamarin.UITest to an iOS app built in Xcode
Objective-C
2
star
68

AndroidCheckBoxSampleApp

A simple app to demonstrate how to interact with an Android CheckBox from a UITest
C#
2
star
69

UITestingWebViews

A demonstration for writing Xamarin.UITests for Web Views inside of a Xamarin.iOS app
C#
2
star
70

WiggleAnimations

A Xamarin.iOS and a Xamarin.Android sample app demonstrating how to imitate a wiggle animation
C#
2
star
71

BarcodeReader

An iOS and Android app to scan/read barcode information. Built using Xamarin.Forms.
C#
2
star
72

Perfect-Gift

A serverless function to verify a perfectly wrapped gift. The solution to #25DaysOfServerless Day 18.
C#
1
star
73

FormsPushNotificationSample

Integrating Push Notifications with a Xamarin.Forms app
C#
1
star
74

UIModalPresentationStyleFormSheetOnAppearingRepro

A Xamarin.Forms sample reproducing a bug where OnAppearing does not fire with a `UIModalPresentationStyle.FormSheet` Page is dismissed
C#
1
star
75

UnitTestAppTemplate

Recommended Unit Test App templates for Visual Studio for Mac
C#
1
star
76

ExpanderSample

A demonstration of Xamarin.Forms.Expander
C#
1
star
77

InvokeOnMainThreadAsync_Repro

Reproduction sample for Xamarin.Forms.InvokeOnMainThreadAsync
C#
1
star
78

XamarinFormsSingletonRepro

Xamarin.Forms sample to reproduce System.MissingMethodException when using a singleton for Application.MainPage
C#
1
star
79

XamMap

A sample app showing how track a user location in iOS
C#
1
star
80

Temp-Async-and-Await

C#
1
star
81

BGBackgroundTaskWorkaround

An iOS sample app demonstrating how to use Background Fetch
C#
1
star
82

GridToRelativeLayout

C#
1
star
83

FormsIllegalArgumentReproduction

Reproduction of the IllegalArgument in Xamarin.Forms when using a Net Standard Library
C#
1
star
84

ContextActionOnAppearingReproduction

Sample Xamarin.Forms app to reproduce ContextActions not working when assign in OnAppearing
C#
1
star
85

ButtonRendererSample

A sample Xamarin.Forms app showing how to make a Button Custom Renderer
C#
1
star
86

CreateInteractiveCharts

An iOS and Android sample app written in Xamarin.Forms, demonstrating how to create interactive charts using Syncfusion
C#
1
star
87

BinarySearchTree

C#
1
star
88

CollectionViewFooterRefreshViewRepro

Reproduction sample for Xamarin.Forms.CollectionView bug
C#
1
star
89

ChangeTabbedPageIconSample

A sample Xamarin.Forms app demonstrating how to update the icon and title of a TabbedPage any time it is tapped
C#
1
star
90

GitHubReadmeRetriever

APIs built using Azure Functions to retrieve GitHub Readme
C#
1
star
91

Xamarin.Forms-NaN-is-not-a-valid-value-for-width-reproduction

A Xamarin.Forms solution to reproduce System.ArgumentException: NaN is not a valid value for width
C#
1
star
92

TextMood_TwilioBlog

Source code for Twilio Blog Post
C#
1
star
93

RealmSampleApp

An iOS an Android app created in Xamarin.Forms using Realm.io for local data storage
C#
1
star
94

XAM320-Willis-Onsite

Sample MVVM app built using Xamarin.Forms during the Willis Towers Watson onsite training, 08 November 2017
C#
1
star
95

ViewCellOnDisappearing

A reproduction of ViewCell.OnDisappearing not firing
C#
1
star
96

URLEncodedFormBug

Reproduction of Xamarin.iOS PostAsync Bug when using FormUrlEncodedContent
C#
1
star
97

WINAPPSDKGENERATEPROJECTPRIFILE_ReproductionSample

This sample reproduces the `WINAPPSDKGENERATEPROJECTPRIFILE` error in CommunityToolkit.Maui-pre7
C#
1
star
98

ChoppedPickerReproduction

Reproduction to demonstrate that a Xamarin.Forms.Picker does not scale horizontally to match its contents
C#
1
star
99

RepeatTabsReproductionSample

Sample app to reproduce multiple tabs bug in Xamarin.Forms
C#
1
star
100

DragCoordinatesUITestRepro

Reproduction of a bug in UITest v2.0.10
C#
1
star