|
Depending on your requirements it may be easier for each application to provide a file or filename for the library to use as its log file.
|
|
|
|
|
Quick question: Will there be a problem if multiple instances of the same application try to write in the same flat file at the same time?
I found following text on MSDN:
You should not configure more than one Flat File sink or Rolling Flat File sink instance to write to the same physical file. However, you can enable the same listener (and sink) on multiple event sources and funnel the events from those multiple event sources to the same file.
Link: Logging events to a disk file[^]
|
|
|
|
|
|
The Microsoft Enterprise Library Enterprise Library 6 – April 2013[^] Has a block which provides a very flexible logging mechanism.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
If you want simple, don't log to a "file" in this case; log to a database.
Any decent logger will support this via configuration options.
|
|
|
|
|
NJdotnetdev wrote: The only question in mind is how I can make sure that only one instance of the
loaded dll is writing to the log file at a given time. You can't. I can create a new AppDomain and load your dll again.
As long as the logger does what it is intended to do (log a message and uniquely identify the origin) things should work, even if loaded more than once, or, multiple versions of the same library
Imagine writing a new product. Some dev finds out how to create a mini-dump, and includes an option to send the mini-dump along with the logging. Your new product uses YourCompanyLogging2.0, the improved logger; whereas the client has a different product on his/her machine which depends on YourCompanyLogging1.0. It knows nothing of the extra filepath it is supposed to send, and would throw and ArgumentNullException if the new routine is launched.
There is a whole host of dragons ahead, and the subject you are diving into is called "DLL HEL". There is no neat solution there.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
The question here is why do you want every one of your DLL instances to write in the same log?
Why not have each instance of your DLL write to a different log? And besides, this probably makes more sense - since each app using your DLL will have its own workflow.
Best,
John
-- Log Wizard - a Log Viewer that is easy and fun to use!
|
|
|
|
|
HiEveryone,
I am automating my .net application using AutomationElement. I want write process synchronization for my framework. Is there any API which can tell us whether application is busy or not?
REegards
Raj
|
|
|
|
|
Define, in precise terms, what a "busy application" is first.
|
|
|
|
|
I have an ObservableCollection and a Property that implements INotefiedPropertyChanged so I want to find out what type the object is, basically:
if ((MyObject is INotifyCollectionChanged)&& (MyObject is INotifyCollectionChanged))
Console.WriteLine("This object implements both INotifyPropertyChanged and INotifyCollectionChanged");
if (!(MyObject is INotifyCollectionChanged) && (MyObject is INotifyCollectionChanged))
Console.WriteLine("This object implements only INotifyPropertyChanged");
And I want to use it to write something like:
public static IObservable<EventPattern<PropertyChangedEventArgs>> Observes<TSource>(this TSource MyObject) where TSource : INotifyPropertyChanged
{
return null;
}
public static IObservable<EventPattern<PropertyChangedEventArgs>> Observes<TSource>(this TSource MyObject) where TSource : INotifyCollectionChanged
{
return null;
}
This last code won't compile as the definitions are considered equal. BTW: I know I can solve the problem by naming the two methods differently, but I want it to be one simple call for both.
|
|
|
|
|
NB: You have some (copy&paste?) mistakes there:
if ((MyObject is INotifyCollectionChanged)&& (MyObject is INotifyPropertyChanged))
Console.WriteLine("This object implements both INotifyPropertyChanged and INotifyCollectionChanged");
if (!(MyObject is INotifyCollectionChanged) && (MyObject is INotifyPropertyChanged))
Console.WriteLine("This object implements only INotifyPropertyChanged");
public static IObservable<EventPattern<PropertyChangedEventArgs>> Observes<TSource>(this TSource MyObject) where TSource : INotifyPropertyChanged
{
return null;
}
public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> Observes<TSource>(this TSource MyObject) where TSource : INotifyCollectionChanged
{
return null;
}
The only way to keep the method names the same would be to have different parameter lists. But that doesn't make sense here. Just name them ObservePropertyChanged and ObserveCollectionChanged and move on
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Well, I could also Say something in the line of
public static IObservable<T> Observes<TSource>(this TSource MyObject) where TSource : object, T: object
{
if ((MyObject is INotifyCollectionChanged)&& (MyObject is INotifyPropertyChanged))
Console.WriteLine("This object implements both INotifyPropertyChanged and INotifyCollectionChanged");
if (!(MyObject is INotifyCollectionChanged) && (MyObject is INotifyPropertyChanged))
Console.WriteLine("This object implements only INotifyPropertyChanged");
}
But then Id have the problem of converting the output to Action<t> from Action<object>. That didnt seem so simple, at least to me.
|
|
|
|
|
For a generic return type the type has to be part of the generic type arguments of the method:
public static IObservable<T> Observes<TSource, T>(this TSource MyObject) where TSource : object, T: object
So this would just move the neccessity to write a different method name to having to write a different type name.
However, if you merged the methods for creating the observable and subscribing to it into one, you wouldn't have to return the generic IObservable but just the non-generic IDisposable subscription object instead.
But: Lifting the type constraint for TSource from IPropertyChanged / INotifyCollectionChanged to Object for the sake of having one method is rather "dirty"
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Sascha Lefèvre wrote: But: Lifting the type constraint for TSource from IPropertyChanged / INotifyCollectionChanged to Object for the sake of having one method is rather "dirty"
Oh yes indeed What I really wanted was a way to write a little more complex where clause, and I thought I might have missed something. I could write where T : INotifyPropertyChange,INotifyCollectionChanged but not a clause that said that it cound not implement some interface.
|
|
|
|
|
Kenneth Haugland wrote: I could write where T : INotifyPropertyChange,INotifyCollectionChanged but not a clause that said that it cound not implement some interface. Yes, that's not possible.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
As it turns out, I was asking the wrong question, thus looking for solutions in the wrong place.
The trick I used was that I created a generic SubscribeWeakly, and it was this method that I really needed:
Weak events in .NET using Reactive Extensions (Rx)[^]
Yeah, question is old now, but in case other people see it they should now be able to solve it
|
|
|
|
|
Thank you, Kenneth, I'll take a look at it
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Hi C# Developers,
Question 1:
How do I suppress Cancel button click event of Save As dialog box to make sure that my users click save button only?
Question 2:
How do I prevent users from creating New folder while Save As dialog box is open?
Question 3:
How do I prevent users from changing the current folders path while Save As dialog box is open?
Your help is much appreciated in advance
Kindest Regards
Lucky Khoza
|
|
|
|
|
1) You can't.
2) You can't.
3) You can't.
It's a system dialog, and as such it exposes system facilities. If you want to restrict what it can do that heavily - and you'll annoy a lot of people if you do - then you need to write your own custom "Save As" dialog and use that instead of the system one.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Issues with customizing the built-in WinForms 'FileDialogs ('Open, 'Save) are discussed thoroughly in these CodeProject articles: [^], [^], [^].
I think it's a mistake to try and alter the appearance (the UI) of these Dialogs; Win users are socialized to expect these dialogs to behave in standard ways, and its tricky coding that will entail things like hooking the underlying Window of a Button, using Win API's, etc.
But, you can certainly exert a strong degree of control by creating a custom 'Filter setting restricting the viewed locations.
If you really want total control of where the user can save a file, why not create a ComboBox with all the valid locations in it; idea: use the 'DisplayMember and 'DisplayMember property to display whatever "friendly" name you think is meaningful to the user, and, perhaps, use the 'ValueMember property to hold the DirectoryInfo, or FileInfo you want associated with the "friendly" name. Put the ComboBox in a UserControl and then 'Show/Hide it as necessary.
In short, if you want the user to have fewer options: give them fewer options.
«In art as in science there is no delight without the detail ... Let me repeat that unless these are thoroughly understood and remembered, all “general ideas” (so easily acquired, so profitably resold) must necessarily remain but worn passports allowing their bearers short cuts from one area of ignorance to another.» Vladimir Nabokov, commentary on translation of “Eugene Onegin.”
|
|
|
|
|
You can't do any of that stuff with the stock SaveDialog.
But, with all those restrictions, you've pretty much limited the user to entering a filename in a TextBox so why even use a SaveDialog at all?
Also, what if the user accidentally click the SaveAs menu item? How are you giving them a way out without performing the Save operation?
modified 2-Feb-16 9:51am.
|
|
|
|
|
Dave Kreskowiak wrote: Also, what if the use accidentally click SaveAs? How are you giving them a way out without performing the Save operation? With a WinForms SaveFileDialog you can define a 'FileDialog.FileOk EventHandler, in which you can cancel the 'Save operation, and keep the dialog open.
private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
{
if (saveFileDialog1.FileName == @"C:\Users\SomeUser\Desktop\NoGo.xxx"
|| saveFileDialog1.FileName.ToLower().Contains("forbidden"))
{
e.Cancel = true;
}
} And, when the SaveFileDialog 'returns is closed: of course, you've got another chance to validate and do nothing based on the selected File. And, you've got the power to restrict files viewed by means of the 'Filter Property.
My preference is to never enable showing any kind of Dialog unless the pre-conditions for its valid use are met. So, yeah, that means disabled MenuItems, or Buttons, etc.
Unfortunately, the FolderBrowserDialog does not expose any Events.
«In art as in science there is no delight without the detail ... Let me repeat that unless these are thoroughly understood and remembered, all “general ideas” (so easily acquired, so profitably resold) must necessarily remain but worn passports allowing their bearers short cuts from one area of ignorance to another.» Vladimir Nabokov, commentary on translation of “Eugene Onegin.”
|
|
|
|
|
Yeah, but that goes against how the standard dialog works from the users perspective and isn't intuitive. Clicking OK to Cancel? I don't think so.
I was referring to someone clicking something like a SaveAs menu item only to realize they clicked on the wrong item. The dialog is being shown now, but how does the user get back intuitively with a Cancel button? I know, the little X in the top right corner or double-clicking the top left corner or hitting Alt-F4 to close the dialog works to do this also but too many users don't know about them.
|
|
|
|
|
More to the point, you can even have a default value that the user can use as the "file name" (probably somehow related to current day/time), so that the user can/will probably just click OK to save it.
And trust me, it's very likely the user will choose that default 95% of the time
Best,
John
-- Log Wizard - a Log Viewer that is easy and fun to use!
|
|
|
|
|
Write your own dialog.
If it's not broken, fix it until it is
|
|
|
|