Is CoreDispatcher the WinRT equivalent to WPF Dispatcher in win8 app store apps? - marshalling

In implementing a producer consumer pattern with an ObservableCollection in WPF I've used marshaling techniques like in this example to ensure that the collection's events get dispatched on the UI thread as items are being created on a worker thread.
In winrt I can see how marshaling using Dispatcher like this:
public void AddItem<T>(ObservableCollection<T> oc, T item)
{
if (Dispatcher.CheckAccess())
{
oc.Add(item);
}
else
{
Dispatcher.Invoke(new Action(t => oc.Add(t)), DispatcherPriority.DataBind, item);
}
}
could switch to CoreDispatcher like this:
public async void AddItem<T>(ObservableCollection<T> oc, T item)
{
if (Dispatcher.HasThreadAccess)
{
oc.Add(item);
}
else
{
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { oc.Add(item); });
}
}
Is that an appropriate use of CoreDispatcher?
Is there a better way to do this for a basic concurrent producer/consumer pattern in winrt?
Without the same static accessor method as Dispatcher do I need to pass CoreDispatcher down from the UI into the marshaling code?

Here's what I've done:
public Screen(IPreConfigurationService preConfigurationService, INavigationService navigationService)
{
_preConfigurationService = preConfigurationService;
_navigationService = navigationService;
if (!IsInDesignMode)
_currentDispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
}
public string UserMessage
{
get { return _userMessage; }
set
{
_userMessage = value;
SafelyRaisePropertyChanged("UserMessage");
}
}
protected void SafelyRaisePropertyChanged(string message)
{
if (!IsInDesignMode)
_currentDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => RaisePropertyChanged(message));
}
protected void ExecuteOnDispatcher(Action action)
{
_currentDispatcher.RunAsync(CoreDispatcherPriority.Normal, action.Invoke);
}
protected void SendUserMessage(string message)
{
UserMessage = message;
_currentDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => AlertOnError(message));
}

Related

IHostedService - background task locks app

I want to run task in different thread which will synchornize data, but it locks whole server (asp net core). i have no idea where i did something wrong.
I tried with tasks, and then with thread, but it always lock my app.
public interface IScopedProcessingService
{
Task DoWork(CancellationToken stoppingToken);
}
public class ScopedProcessingService : IScopedProcessingService
{
private int executionCount = 0;
private readonly ISynchronizationBackgroundService _syncService;
public ScopedProcessingService(ISynchronizationBackgroundService syncService)
{
_syncService= syncService;
}
public Task DoWork(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
_syncService.Synchronize();
}
catch (Exception ex)
{
Log.Error($"SYNCHRONIZATION ERROR {ex.Message} {ex.InnerException?.Message}");
}
Thread.Sleep(5000);
}
return Task.CompletedTask;
}
}
and the consumer
public class ConsumeScopedServiceHostedService : BackgroundService
{
public IServiceProvider Services { get; }
public ConsumeScopedServiceHostedService(IServiceProvider services)
{
Services = services;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
Thread t = new Thread(() =>
{
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedProcessingService>();
scopedProcessingService.DoWork(stoppingToken);
}
});
t.Start();
return Task.CompletedTask;
}
}
and in the end registration:
services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<IScopedProcessingService, ScopedProcessingService>();
services.AddScoped<ISynchronizationBackgroundService, SynchronizationBackgroundService>();
Would be grateful for any advice.

.Net 6 How detect action filter is on Controller or Action method

I have an action filter like this:
public class TestAttribute : IAsyncActionFilter, IOrderedFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var onController= ?//here I want to detect whether attribute is on controller or action
}
public int Order { get; }
}
And I put attribute on controller like this (I know for sake of this purpose you need to use IFilterFactory or ServiceFilter but I removed them for simplicity):
[Test]
public class FileController : BaseApiController
Or for Action methods:
[Test]
public async Task<ActionResult<FileResponse>> UploadAsync()
So my question is how to detect this attribute is execute for controller scope or action scope in .net 6?
This code will help you;
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var currentFilter = context.ActionDescriptor
.FilterDescriptors
.FirstOrDefault(filterDescriptor => ReferenceEquals(filterDescriptor.Filter, this));
if (currentFilter == null)
{
return;
}
if (currentFilter.Scope == FilterScope.Action)
{
//..
}
if (currentFilter.Scope == FilterScope.Controller)
{
//...
}
await next();
}

Can a SignalR Hub receive events from clients? And if so, how?

I have a signalR hub that needs to be able to receive an event from a client and then notify all other clients connected to the hub.
Is that possible?
I want my 'hub' application to be able to receive messages and send them. I can only figure out how to do the sending of messages. Here is what I have now:
Application 1-- Hub
Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSignalR().AddHubOptions<EventsHub>(options =>
{
options.HandshakeTimeout = TimeSpan.FromMinutes(5);
options.EnableDetailedErrors = true;
});
services.AddTransient(typeof(BusinessLogic.EventsBusinessLogic));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseSignalR((configure) =>
{
configure.MapHub<EventsHub>("/hubs/events", (options) =>
{
});
});
}
Set Up of the Hub in Application 1
public class EventsHub : Hub
{
public EventsHub()
{
}
public override Task OnConnectedAsync()
{
if (UserHandler.ConnectedIds.Count == 0)
{
//Do something on connect
}
UserHandler.ConnectedIds.Add(Context.ConnectionId);
Console.WriteLine("Connection:");
return base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
//Do something on Disconnect
}
public static class UserHandler
{
public static HashSet<string> ConnectedIds = new HashSet<string>();
}
}
BusinessLogic:
public class EventsBusinessLogic
{
private readonly IHubContext<EventsHub> _eventsHub;
public EventsBusinessLogic(IHubContext<EventsHub> eventsHub)
{
_eventsHub = eventsHub;
}
public async Task<Task> EventReceivedNotification(ProjectMoonEventLog eventInformation)
{
try
{
await _eventsHub.Clients.All.SendAsync("NewEvent", SomeObject);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
}
In the second application, that listens for events or messages from the hub:
Startup.cs
private static void ConfigureAppServices(IServiceCollection services, string Orale, string Sql)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddOptions();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//set up of singletons and transients
services.AddHostedService<Events.EventingHubClient>();
}
The ClientHub to connect to application 1:
public class EventingHubClient : IHostedService
{
private HubConnection _connection;
public EventingHubClient()
{
_connection = new HubConnectionBuilder()
.WithUrl("http://localhost:61520/hubs/events")
.Build();
_connection.On<Event>("NewEvent",
data => _ = EventReceivedNotification(data));
}
public async Task<Task> EventReceivedNotification(Event eventInformation)
{
try
{
//Do something when the event happens
return Task.CompletedTask;
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
// Loop is here to wait until the server is running
while (true)
{
try
{
await _connection.StartAsync(cancellationToken);
Console.WriteLine("Connected");
break;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
await Task.Delay(100);
}
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return _connection.DisposeAsync();
}
}
This works, but now I want application 2 to be able to send a message to application 1? So I need a similar piece of code as in the EventsBusinessLogic class in application2 to send messages to application 1.
I hope this is clear enough? Is this the purpose of SignalR?
Please refer to signalR documentation signalR documentation for .net client
I guess in your Hub method like this
public async Task SendTransaction(Transaction data)
{
await Clients.All.SendAsync("TransactionReceived", data);
}
Then add methods in client side
in constructor add
connection.On<Transaction>("TransactionReceived", (data) =>
{
this.Dispatcher.Invoke(() =>
{
var transactionData = data;
});
});
and then SendTransaction expected on server
private async void SendTransaction(Transaction data)
{
try
{
await connection.InvokeAsync("SendTransaction", data);
}
catch (Exception ex)
{
//
throw
}
}

Retrofit Rxjava error handler

I have a service class which is used to call api requset
here is an example method:
public Observable<List<Category>> test(Location location, int radius) {
Observable<CategoryListResponse> observable = api.test();
return observable
.doOnNext(new Action1<CategoryListResponse>() {
#Override
public void call(CategoryListResponse categoryListResponse) {
//handle error
}
})
.flatMap(new Func1<CategoryListResponse, Observable<Category>>() {
#Override
public Observable<Category> call(CategoryListResponse categoryListResponse) {
return Observable.from(categoryListResponse.getCategories());
}
})
.map(new Func1<Category, Category>() {
#Override
public Category call(Category category) {
//do something...
return category;
}
})
.toList();
}
And subscribe() will be called in another class.
observable.subscribe(new Action1<List<Category>>() {
#Override
public void call(List<Category> categories) {
//on success
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
//on error
}
});
I was thinking to do error handling in the doOnNext() before it is returned back. but how can I trigger onError()?
You should throw a runtime exception and control the exception in onError operator in case that happens
Observable<CategoryListResponse> observable = api.test();
return observable
.doOnNext(list -> {
try{
request(list);
catch(Exception e){
throw new RuntimeException(e);
}
}).onError(t->//Here you control your errors otherwise it will be passed to OnError callback in your subscriber)
.flatMap(item -> Observable.from(item.getCategories()))
.map(category-> category)
.toList();
}
Try to use lambdas, make your code much more clear and readable
You can see some RxJava examples here https://github.com/politrons/reactive

NInject kernel GetAll returns empty

I've two projects (class library projects) which implement one interface:
The first one:
public class MailPlugin : Extensibility.IProductorPlugin
{
...
}
The second one:
public class FileSystemPlugin : Extensibility.IProductorPlugin
{
...
}
Extensibility.IProductorPlugin, is a interface of a third project:
namespace Extensibility
{
public delegate void NotifyDigitalInputs(List<Domain.DigitalInput> digital_inputs);
public interface IProductorPlugin
{
String Name { get; }
String Description { get; }
String Version { get; }
List<Domain.Channel> AvailableChannels { get; }
IEnumerable<Guid> TypeGuids { get; }
event NotifyDigitalInputs OnDigitalInputs;
}
}
In my composition root, I've created this class:
namespace UI
{
public sealed class NinjectServiceLocator
{
private static readonly Lazy<NinjectServiceLocator> lazy = new Lazy<NinjectServiceLocator>(() => new NinjectServiceLocator());
public static NinjectServiceLocator Instance { get { return lazy.Value; } }
public Ninject.IKernel Kernel { get; private set; }
private NinjectServiceLocator()
{
using (var k = this.Kernel = new Ninject.StandardKernel())
{
k.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProductorPlugin))
.BindAllInterfaces()
);
}
}
}
}
So, when I want to look for all plugins, I just perform this:
protected void initialize()
{
foreach (Extensibility.IProductorPlugin productor_plugin in NinjectServiceLocator.Instance.Kernel.GetAll(typeof(Extensibility.IProductorPlugin)))
{
using (var channel_tile = new DevExpress.XtraBars.Docking2010.Views.WindowsUI.Tile() { Group = "Plugin Channels" })
{
foreach (Domain.Channel channel in productor_plugin.AvailableChannels)
{
channel_tile.Elements.Add(new DevExpress.XtraEditors.TileItemElement() { Text = channel.Name });
channel_tile.Elements.Add(new DevExpress.XtraEditors.TileItemElement() { Text = channel.Description });
this.tileContainer1.Items.Add(channel_tile);
}
}
}
}
However, GetAll returns anything.
What am I doing wrong?
I'll appreciate a lot your help.
Thanks for all.
try removing the using() from around the Kernel instantiation. a using will dispose the object at the end of the scope, which we don't want for a kernel.
using (var k = this.Kernel = new Ninject.StandardKernel())