Created
December 4, 2022 14:28
-
-
Save Platonenkov/4c2cb02dacc0fa0df1dcce6920a6c814 to your computer and use it in GitHub Desktop.
Async Converter for wpf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AsyncConverter : MarkupExtension, IValueConverter | |
{ | |
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) | |
{ | |
var task = Task.Run(async () => | |
{ | |
await Task.Delay(3000); | |
return "Async operation"; | |
}); | |
return new TaskCompletionNotifier<string>(task); | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) | |
{ | |
return null; | |
} | |
public override object ProvideValue(IServiceProvider serviceProvider) | |
{ | |
return this; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Image DataContext="{Binding Converter={converters:NFTImageLoadConverter}}" | |
Source="{Binding Path=Result, UpdateSourceTrigger=PropertyChanged}" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Threading.Tasks; | |
namespace TaskConverters; | |
public interface ITaskCompletionNotifier<TResult> : ITaskCompletionNotifier | |
{ | |
new Task<TResult> Task { get; } | |
TResult Result { get; } | |
} | |
/// <summary> | |
/// Watches a task and raises property-changed notifications when the task completes. | |
/// </summary> | |
public interface ITaskCompletionNotifier : INotifyPropertyChanged | |
{ | |
Task Task { get; } | |
TaskStatus Status { get; } | |
bool IsCompleted { get; } | |
bool IsSuccessfullyCompleted { get; } | |
bool IsCanceled { get; } | |
bool IsFaulted { get; } | |
AggregateException Exception { get; } | |
Exception InnerException { get; } | |
string ErrorMessage { get; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace TaskConverters; | |
/// <summary> | |
/// Watches a task and raises property-changed notifications when the task completes. | |
/// </summary> | |
/// <typeparam name="TResult"></typeparam> | |
public sealed class TaskCompletionNotifier<TResult> : ITaskCompletionNotifier<TResult> | |
{ | |
public TaskCompletionNotifier(Task<TResult> task) | |
{ | |
Task = task; | |
if (!task.IsCompleted) | |
{ | |
var scheduler = (SynchronizationContext.Current == null) ? TaskScheduler.Current : TaskScheduler.FromCurrentSynchronizationContext(); | |
task.ContinueWith(t => | |
{ | |
var propertyChanged = PropertyChanged; | |
if (propertyChanged != null) | |
{ | |
propertyChanged(this, new PropertyChangedEventArgs("IsCompleted")); | |
if (t.IsCanceled) | |
{ | |
propertyChanged(this, new PropertyChangedEventArgs("IsCanceled")); | |
} | |
else if (t.IsFaulted) | |
{ | |
propertyChanged(this, new PropertyChangedEventArgs("IsFaulted")); | |
propertyChanged(this, new PropertyChangedEventArgs("ErrorMessage")); | |
} | |
else | |
{ | |
propertyChanged(this, new PropertyChangedEventArgs("IsSuccessfullyCompleted")); | |
propertyChanged(this, new PropertyChangedEventArgs("Result")); | |
} | |
} | |
}, | |
CancellationToken.None, | |
TaskContinuationOptions.ExecuteSynchronously, | |
scheduler); | |
} | |
} | |
// Gets the task being watched. This property never changes and is never <c>null</c>. | |
public Task<TResult> Task { get; private set; } | |
Task ITaskCompletionNotifier.Task => Task; | |
public TResult Result => (Task.Status == TaskStatus.RanToCompletion) ? Task.Result : default(TResult); | |
public TaskStatus Status => Task.Status; | |
public bool IsCompleted => Task.IsCompleted; | |
public bool IsSuccessfullyCompleted => Task.Status == TaskStatus.RanToCompletion; | |
public bool IsCanceled => Task.IsCanceled; | |
public bool IsFaulted => Task.IsFaulted; | |
public AggregateException Exception => Task.Exception; | |
public Exception InnerException => (Exception == null) ? null : Exception.InnerException; | |
public string ErrorMessage => (InnerException == null) ? null : InnerException.Message; | |
public event PropertyChangedEventHandler PropertyChanged; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment