So I want the Webrole to react to Configuration changes, which involved capturing the event "Changing" and update a static dictionary (contains my Features setup)
Sounds like a simple task, it just I then realised that any changes made in the static object in WaIISHost (which handle the Changing event) is not accessible by the W3WP process.
I'm thinking of using either a message queue (using Azure queues) or Anonymous Pipe (but still don't know how to set that up)
Anyone knows how to either passon the Changing/Changed event from the WaIISHost process to W3WP, or if not possible, best way (i.e. least complicated) to communicate between the 2?
Many thanks!
You can subscribe to the RoleEnvironment events from within w3wp.exe and then the events will be raised in both processes (w3wp.exe and WaIISHost.exe). Global.asax is a good place to do this.
Related
Background: I have a simple ASP.NET Core 3.1 site. Very rarely (three or four times per week), a user might fill out a form that triggers an email to be sent.
I don't want to delay the page response while running the 'send email' operation (even though it only takes a second or two), so from everything I've read, it seems like the code that should handle the email should be a background worker/hosted service, and the Razor pages code should place the data object to be sent in a collection that gets monitored by the background service.
What I'm not fully understanding is why this is necessary in modern ASP.NET Core.
If I was doing this in a normal C# application (not ASP), I'd simply make the 'send email' method async (it's using MailKit, which has async methods), and call the async method without awaiting, allowing the the work be done on the threadpool while allowing the response thread to continue.
But existing answers and blog posts say that calling an async method without an await in ASP is dangerous, due to the fact that IIS can restart ASP processes (application pool recycling).
Yet, most things I've read say Application Recycling is an artifact of old ASP when memory leaks were common, and it's not really a thing on .Net Core. Additionally, many ASP applications aren't even hosted in IIS anymore.
Further, as far as I can tell, IHostedService/Background Worker objects aren't doing anything special - they don't seem to add any additional threading; they just look like singletons that have additional notification for environment startup and shutdown.
So:
Is calling a fire-and-forget async method in ASP.NET Core still considered poor practice, especially if the fire and forget task is short-lived? If so, why? [see edit below for clarification]
Other than notifications for shutdown, is there any reason why a background service is considered better than borrowing a managed threadpool thread (via Task.Run or QueueBackgroundWorkItem)? Wouldn't waking a background service (if it was awaiting on object to be placed in a collection) consume a pool thread in the same way?
Edit: I acknowledge that starting a task, and reporting success to the user, when there's a chance that operation could be terminated, is poor form. There's benefit to being notified of a shutdown and being able to finalize tasks.
Perhaps a better question is, does the old behavior of cycling still exist in modern ASP (on IIS or Kestrel)? Are there other reasons an orderly shutdown might be triggered (other than server shutdown/manual stop)?
I would still call it a poor practice.
The main concern here as well as in the referenced post is mainly about the promise of task completion.
Without being aware of the ghost background tasks, the runtime will not be able to notify the tasks to gracefully stop. This may or may not cause serious issues depending on the status of the tasks at the point the termination occurs.
Using fire forget task often means, your task is at the risk of having to start all over again when the process restarts. And sometimes this is not possible due to loss of context. Imagine your fire-forget task is calling another web API with parameters provided by a web request. The parameters are likely to get wiped out from memory if the process restarts.
And remember, the recycling is not always triggered by IIS / server. It could also be triggered by people. Say when your application runs into a memory leak issue, and you may want to recycle the app process every 1 hour as a temporary relief. Then you need to make sure you don't break your background tasks.
In terms of hosting - it is still possible to host ASP.Net Core applications in-process, in which the app pool gets recycled by IIS after a configured time period, or by default 29 hours.
In terms of lifetime - hosted services are types you register to DI, so DI features could be used, for example, this built-in hosted service implements IDisposable, which means proper clean up could be done upon shutting down.
Frankly, background tasks and hosted services both allow you to do fire and forget. But when you need reliability and resilience, hosted services win.
To answer the second half of your question, the app will wait for all hosted services' StopAsync methods to finish before shutting down. As long as you await your Tasks in the hosted service, this effectively means you can assume your Tasks will be allowed to finish running before the app shuts down. The app could still be force-shutdown, which in that case, nothing is guaranteed anymore.
If you need more guarantees about your background tasks, you should move them to run in a separate process. You could use something like Runly to make it easier to break out functionality into background jobs. It also makes it easy to provide real-time feedback to the user so that you are not lying to the user when you say "everything is done" while something is still running in the background.
Full disclosure: I cofounded Runly.
I try to develop an extension for Microsoft Edge based on native messaging and the official guide provides the example. And there is synchronization of access to the dictionaries of AppServiceConnections and their Deferrals in the OnBackgroundActivated method, but there is no such a thing in other event handling methods...
So my question is about UWP App Service threading model. Is it guaranteed that only one event handling method can be performed at a time? Or should I provide a correct synchronization of access to my data?
Is AppServiceConnection thread safe? Can I use SendMessageAsync from different threads at the same time? Or should I synchronize its usage?
I guess your issue is that you didn't see lock keyword inside events like OnAppServiceRequestReceived, OnAppServicesCanceled and so on, which is to do thread synchronization, and you're not sure if you should do this by yourself.
I think the answer should be no.lock inside OnBackgroundActivated is ensured to set correct desktopBridgeConnectionIndex or connectionIndex. Without the keyword lock inside these event handles not means that the event handle must be triggered only one time at a time. For one app service, if client A is connecting the app service, at the same time, another client B asks for the same app service, for this scenario the app service will spin up another instance of the same background task. So that for client A, its app service connection there is no side effect on client App B. In another words, each app service connection has its own instance, messages sending based on one app service connection have no influence with others. You may reference this video to look more details about app service, app service relative is about starting from 25th minute.
If you check the code snippet inside the event, you may see there are code lines to judge the request is from which app service connection, for example this.desktopBridgeConnection = desktopBridgeConnections[this.currentConnectionIndex].You will send message to correct AppServiceConnection, and this should be thread safe. If you met actual thread save issue when performing this, you could ask issue with testing details.
I'm developing a web application subscribing to NServiceBus events being published by a backend application. With one worker process this works as expected, but with multiple IIS worker processes on the same IIS server, only one process receives the events. I suppose this is due to all worker processes sharing the same input queue and therefore "stealing" events from each other. My question therefore is how to ensure that the event handlers in every worker process receive the events they have subscribed to?
While generating input queue names dynamically would solve the problem, it would soon leave a lot of unused queues around the system.
This sounds like a pretty common problem and so should have a common solution?
ANy feedback would be appreciated
/Magnus
Unfortunately NServiceBus does not support web gardens.
We will consider adding support for web gardens in the future, based on user demand.
We suggest for the mean time to consider virtualization as a scale out solution instead.
I have raised an issue, see https://github.com/Particular/NServiceBus/issues/2015, please consider adding extra comments to the issue.
I'm currently building a C# application which will automatically authenticate a user against certain network resources when they connect to specific wireless networks.
At the moment, I'm using the Managed Wifi API to discover when a user connects / disconnects from a wireless network. I have an event handler, so that when any of these activities occurs, one of my methods is called to inspect the current state of the wireless connection.
To manage the state of the application, I have another class which is called the "conductor", which performs the operations required to change the state of the application. For instance, when the wireless card connects to the correct network, the conductor needs to change the system state from "Monitoring" to "Authenticating". If authentication succeeds, the conductor needs to change the state to "Connected". Disconnection results in the "Monitoring" state again, and an authentication error results in an "Error" state. These state changes (if the user requests) can result in TrayIcon notifications, so the user knows that they are being authenticated.
My current idea involves having the method used to inspect the current state of the wireless call the "authenticate" or "disconnect" methods within the state manager. However, I'm not sure if this is an appropriate use of the event handler -- should it instead be setting a flag or sending a message via some form of IPC to a separate thread which will begin the authentication / disconnection process?
In addition to the event handler being able to request connection / disconnection, a user can also perform it via the tray icon. As a result, I need to ensure these background operations are not blocking the tray's interactions with the user.
Only one component should be able to request a change of the system state at any time, so I would need to use a mutex to prevent concurrent state changes. However, how I should synchronous the rest of these components is a slight mystery to me.
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
EDIT: Most importantly, I want to verify that an event will be executed as a separate thread, so it cannot block the main UI. In addition, I want to verify that if I have an event handler subscribed to an event, it will handle events serially, not in parallel (so if the user connects and disconnects before the first connection event is processed, two state changes will not be occurring simultaneously).
Any advice or literature I should read would be appriciated. I have no formal training in C# language, so I apologize if I've misstated anything.
That explains a few things. :)
I would read up on threads, event handling, and creation of system tray icons/interfaces.
It is important to note the following:
Events are processed on the same thread they are called from. If you want the processing of an event not to lock the GUI then you will need to have the button move the work to a different thread.
When an event is fired it passes the appropriate arguments to all the methods in its list. This is pretty much the same as calling one method which in turn calls all the others (see EventFired example). The purpose of events is not to call methods as we can do that already, it is to call methods which may not be known when the code is compiled (the click event on a button control would not be known when the library the control is in is compiled for example). In short, if you can call the method instead of using an event the do so.
void EventFired(int arg1, object arg2)
{
subscribedMethod1(arg1, arg2);
SubscribedMethod2(arg1, arg2);
SubscribedMethod3(arg1, arg2);
SubscribedMethod4(arg1, arg2);
SubscribedMethod5(arg1, arg2);
SubscribedMethod6(arg1, arg2);
SubscribedMethod7(arg1, arg2);
}
If you want to prevent a user interface from locking do the work on another thread. Remember though, user interface elements (forms, buttons, grids, labels, etc.) can only be accessed from their host thread. Use the control.Invoke method to call methods on their thread.
Removing an option from an interface is not a good way to prevent raceway conditions (the user starts a connect/disconnect while one is already running) as the user interface will be on a different thread and could be out of sync (it takes time for separate threads to sync up). While there are many ways to resolve this problem, the easiest for someone new to threading is to use a lock on the value. This way .NET will make sure only one thread can change the setting at a time. You will still need to update the user interface so the user knows the update is occurring.
Your general design sound fine. You could use 2-3 threads (1 for the user interface (tray icon), 1 for checking for new network connections, and 1 (could be merged with connection check) which checks the internet connection.
Hope this helps, let us know if you need more (or accept an answer).
As an option, alternative...
If I were you, and since you're starting anew anyway, I would seriously consider the
Rx Reactive Extensions
It gives a completely fresh look at events and event based programming and helps a lot exactly with the things you're dealing with (including synchronizing, dealing with threads, combining events, stopping, starting etc. etc.).
It might be a bit of a 'steep curve' to learn at start, but again, it might be worth it.
hope this helps,
To me it seems that you're going to overengineer the project.
You basically need to implement an event in Commander and in main application subscribe to them. That is.
If there is always one component can make a change and you can have more then one, using some sync mechanism, like a Mutex noted by you, is perfectly valid choice.
Hope this helps.
If you want to have at most one state change pending at any time it is probably best to have the event handlers of the external events you are listening to hold a lock during their execution. This ensure an easy way to program because you are guaranteed that the state of your app does not change underneath you. A separate thread is not needed in this particular case.
You need to make a distinction between the current state of the application and the target state. The user dictates the target state ("connected", "disconnected"). The actual state might be different. Example: the user wants to be disconnected but the actual state is authenticating. Once the authentication step is completed the state machine must examine the target state:
targetState == connected => set current state to connected
targetState == disconnected => begin to disconnect and set state to disconnecting
Separating actual and target state allows the user to change his mind any time and the state machine to steer towards the desired state.
It's hard to give a precise answer without seeing the whole (proposed) structure of your app. But in general, yes, it's OK to use an event hander for that sort of thing - though I'd probably move the actual implementation out to a separate method, so that you can more easily trigger it from other locations.
The comment about disabling the "Connect" button sounds right on to me, though it's quite conceivable you might need other forms of synchronization as well. If your app doesn't need to be multi-threaded, though, I'd steer away from introducing multiple threads just for the sake of it. If you do, look into the new Task API's that have been included as part of the Task Parallel Library. They abstract a lot of that stuff fairly well.
And the comment about not over-thinking the issue is also well-taken. If I were in your shoes, just beginning with a new language, I'd avoid trying to get the architecture just right at the start. Dive in, and develop it with the cognitive toolset you've already got. As you explore more, you'll figure out, "Oh, crap, this is a much better way to do that." And then go and do it that way. Refactoring is your friend.
I'm trying to build a planner web app using ASP.NET MVC 3.
One of the problem I don't know is how to automatically trigger an event(send mail whatever) when the time is one that spot?
Who can help? Thanks.
In addition to your front end asp.net site that allows configuration of events, you will need a backend service attached to the database that sends out the notifications. This back end service should keep track of the last time it processed events. It will wake up periodically and process all newer events. The period will be determined by how 'real time' you want your responses. Once every minute is probably as fine grain as you may need.
Personally I would not make the web app handle that. Instead, I'd have a service that runs in the background or use the Windows Schedule to run certain application every x min/hour.
But with ASP.NET, you could start a background thread that calls some function every x time.
Here's more on that: http://flimflan.com/blog/SafelyRunningBackgroundThreadsInASPNET20.aspx
I hope this helps you in the right direction.
Timed events can be handled with threads or a service.
The downside to threads and timers that's not often considered is that often IIS will restart, which will restart your threads and timers. A service is much more stable and will fire automatically every so often without requiring you to keep track of state data (such as the current time).
A service or a scheduled task is the best fit for this problem, but if your hosting provider (assuming you aren't self-hosting) does not allow for this, or they want a lot more money for this ability, then an alternative you can consider,if running in .NET 4.0, it always having the application pool stay alive.
This blog post by Scott Guthrie describes how this can be done:
http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx