Should I be describing what the user did correctly or incorrectly, or simply what was expected?
If you don't describe the "incorrectly" and "what was expected", the user is lost and cannot make a change. What they did correctly is obvious, since it's not invalid.
What they did incorrectly tells them what to change.
What's expected should tell them what kind of change to make.
How much detail can the user read before they get annoyed?
Varies from user to user. There's no general answer. And there's no easy way to know. Experienced users want short messages. N00bz need long messages. And you can't know the user's level of expertise until after they complain about the messages.
How do I decide between phrases like "must not," "may not," or "cannot"?
You can't decide. It's not your choice. It's your users. In American English (which doesn't even use "shall" except in legal documents) the differences are minor and vary by user. Each user has a personal level of discomfort (or comfort). You can't know the user's level of comfort until after they complain about the messages.
Generally, folks don't like computers telling them way they "must" do. Other than that, it's individual preferences.
This can depend on the project, but how should the information be delivered to the user?
Um... This makes no sense. If the data's invalid, you can't go forward.
Should it be obtrusive (e.g. JavaScript alerts) or friendly?
This makes no sense. "obtrusive" and "friendly" aren't orthogonal.
Should they be displayed prominently? Immediately (i.e. without confirmation steps, etc.)?
This makes no sense. If the data's invalid, then they can't go on, so it has to be prominent.
Do you bother logging validation errors?
Talk to your lawyers about the consequences of users making entry errors. In the medical field, it might matter. In other fields, it rarely matters. If you're fine-tuning your presentation, you'll want to log things so you can figure out what the most common error is and re-engineer things so it cannot possibly be made. If your users are all n00bz (because the app never existed before) you'll need to log things so you can work out the real use cases. If your users are all experts, don't bother logging.
How do I cater to the majority of users?
You can't. Preferences for support and guidance vary by individual person, their level of expertise and their overall comfort with computers and the application. Broad cultural generalizations are less important than individual ones.
The most common solution for this kind of problem is: try to design your C# application in a way it does not have to react to changes within your database. Even when using a "real" client/ server database where you have things like triggers available, most client/server applications avoid the need for a "push model" where the server has to send a "trigger event" to the client. Indeed, there are only few databases which provide such a mechanism. At least client applications typically don't rely on getting all events, since the network between client and server may fail sometimes.
Of course, I don't know your requirements, and how much scope is left for dicussing them, and some requirements can be really hard to be implemented without an appropriate event mechanics.
If you really need this, I guess polling is the only option you have.
Would it probably be an acceptable solution to outsource the polling activity in a separate thread and notify the rest of the application by events?
Technically: probably yes, but you have to measure the performance for your specific case. Crucial factors are how much data has to be scanned in each cycle, and which latency is acceptable (seconds? ok. miliseconds or fewer? may become hard).
Best Answer
If logging to the DB, where would you log db failures, like the DB being unavailable?
Yes, if logging to the file system, the file system could become unavailable, but my guess is that you then would have other things to worry about...
In a server application (not a web server, but one under heavy load anyway), we log to files (several), using a specialist logging component. And while performance is a crucial factor in many parts of the code, we have yet to feel the need to decrease our logging because of performance considerations.
Probably because most logging is done outside of the time critical code. Which is only "natural" because time critical code often would produce way too many log messages to be of any practical use.