|
I was not able to reproduce your problem. Perhaps you have more than one count on the Mutex?
|
|
|
|
|
I have only one mutex. I've temporary "solved" the problem by sleeping 1000 mls before (re)starting same process (to let Mutex time to Releas )
|
|
|
|
|
Zilo(svk) wrote: I have only one mutex.
Yes I know but you may have a count on it greater than ONE.
Zilo(svk) wrote: I've temporary "solved" the problem by sleeping 1000 mls before (re)starting same process
I did not need to sleep. I suspect you have a bug in your code.
|
|
|
|
|
I have a wrapper class for Mutex described in here
I create one Mutex instance per one application instance, releasing that instance when application finished (before restarting).
logically, i should have a bug somewhere, but where
zilo
|
|
|
|
|
Zilo(svk) wrote: I create one Mutex instance per one application instance, releasing that instance when application finished (before restarting).
Yes, exactly what I tested, and I have no wrapper class because I don't need one to do that.
class MutexTest
{
private Mutex _mut = new Mutex(false, "MutexTest");
public void Run()
{
_mut.WaitOne();
Console.WriteLine("MutexTest has mutex... going to sleep...");
Thread.Sleep(10000);
Console.WriteLine("MutexTest releasing");
_mut.ReleaseMutex();
}
public bool IsLocked()
{
return _mut.WaitOne(0, false);
}
}
class Program
{
static int Main(string[] args)
{
MutexTest mt = new MutexTest();
if (!mt.IsLocked())
Console.WriteLine("Second Instance... exiting");
else
{
mt.Run();
System.Diagnostics.Process.Start("ConsoleRnd.exe");
Console.WriteLine("Complete....");
}
return 0;
}
|
|
|
|
|
Try this one:
<br />
<br />
public class SingleProgramInstance : IDisposable<br />
{<br />
private Mutex __mutex;<br />
private bool __firstInstance = false;<br />
private string __uniqueName = String.Empty;<br />
<br />
private Mutex Mutex<br />
{<br />
get { return __mutex; }<br />
private set { __mutex = value; }<br />
}<br />
<br />
public string UniqueName<br />
{<br />
get { return __uniqueName; }<br />
private set { __uniqueName = value; }<br />
}<br />
<br />
public SingleProgramInstance()<br />
: this(String.Empty)<br />
{ }<br />
<br />
public SingleProgramInstance(string identifier)<br />
{<br />
<br />
this.UniqueName = Assembly.GetExecutingAssembly().GetName().Name + identifier;<br />
<br />
this.Mutex = new Mutex(true, this.UniqueName, out __firstInstance);<br />
}<br />
<br />
~SingleProgramInstance()<br />
{ <br />
this.Dispose();<br />
}<br />
<br />
public bool IsFirstInstance<br />
{<br />
get { return __firstInstance; }<br />
} <br />
<br />
public void Dispose()<br />
{<br />
if (this.IsFirstInstance && this.Mutex != null)<br />
{<br />
this.Mutex.ReleaseMutex();<br />
this.Mutex = null;<br />
<br />
GC.SuppressFinalize(this);<br />
} <br />
} <br />
}<br />
<br />
class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
using (SingleProgramInstance spi = new SingleProgramInstance("zxy123"))<br />
{<br />
if (spi.IsFirstInstance) <br />
Console.WriteLine("First Instance"); <br />
<br />
else <br />
Console.WriteLine("!!!!! NOT First Instance !!!!!!"); <br />
<br />
spi.Dispose();<br />
}<br />
<br />
Console.ReadKey();<br />
<br />
Process.Start("test73_Mutex.exe");<br />
}<br />
}<br />
<br />
this fails from time to time
zilo
|
|
|
|
|
Zilo(svk) wrote: this fails from time to time
Yes it would. The code in the main() method does not reflect the desired behavior as you described it in your original post. This would also be known as "a bug".
|
|
|
|
|
Can you be more specific ?
looks like I'll use your solution.
Anyway thank you very much!!!
|
|
|
|
|
Zilo(svk) wrote: looks like I'll use your solution.
Oh dear, that's why I don't normally post code. You should only use your solution. This requires your doing the work to understand what you are doing.
Zilo(svk) wrote: Can you be more specific ?
Yes, here is what you said:
Zilo(svk) wrote: I have an application and I want to keep only one instance running
The code in your main() method cannot possibly do that since you release the Mutex at the start of the application rather than right before it ends.
Also:
Zilo(svk) wrote: I have an application and I want to keep only one instance running
Restarting the application from itself just doesn't make any sense. If you want an instance running and you already have an instance running then you have already satisfied that requirement so no action needs to be taken.
|
|
|
|
|
led mike wrote:
Oh dear, that's why I don't normally post code. You should only use your solution. This requires your doing the work to understand what you are doing.
I never use code only by copying it, that's not the way I work. I always try to understand it. That, of course, doesn't mean that I'm going to dig for every method I see in MSDN just to be 110% sure, that's a waste of time. I was satisfied with explanation in article where my code comes from, maybe I missed something ?!
led mike wrote:
The code in your main() method cannot possibly do that since you release the Mutex at the start of the application rather than right before it ends.
I release Mutex after all work is done, that means main application form and all application resources are disposed (which was not in that example to keep it simple), as I wrote in first post. After Mutex is released I can restart application in certain case (not always of course). Obviously I cannot run restarting sequence before Mutex is released.
led mike wrote:
Restarting the application from itself just doesn't make any sense. If you want an instance running and you already have an instance running then you have already satisfied that requirement so no action needs to be taken.
Restarting application makes exactly same sense as restarting windows for instance. When application starts, certain key resources are loaded, that may not be refreshed/reloaded while application runs (for simplicity reasons). I need to keep only one instance because using(modifying) those key resources by two application instances at one time would cause possible errors...
|
|
|
|
|
Zilo(svk) wrote: that may not be refreshed/reloaded while application runs (for simplicity reasons)
What simplicity? You are now complicating the application with this restart scenario to avoid complicating it? You can't have your cake and eat it too. I highly recommend you abandon this hack and solve the problem of refreshing those resources you mentioned.
|
|
|
|
|
Application restart is small price for implementing refreshing scenario. Believe me. I'm not talking about some simple application. Restarts are not meant to occur every day, they are rather occasional, when significant changes are made (adding new sub-applications, refreshing licenses and objects bound to them, etc...)
However, it looks that you're not willing to bless my mind with a reason why it doesn't work my way )
...though, it's been nice talking to you. What do you do ?
|
|
|
|
|
Zilo(svk) wrote: However, it looks that you're not willing to bless my mind with a reason why it doesn't work my way
At this point I don't think I have ever understood what you have said. When I run your code it behaves exactly as I expect it would. My code behaves differently because it is different.
In both cases the usage of the Mutex to verify single instance status works correctly, it is the remainder of the code that is different. Your code correctly identifies that it is a second instance but then continues to launch another instance prior to exiting. My code correctly identifies that it is a second instance and exits directly without launching another instance.
|
|
|
|
|
I disagree
Lets talk in steps :
Assuming:
Mutex is identified by unique name, which only my app knows and uses.
If I dont get Mutex ownership immediately, I don't wait for it (Mutex.WaitOne()), that means I don't have anything to Release.
1. Very first app launch, try to get ownership of Mutex, receives it because Mutex is not owned by any other processes.
2. Do whatever app does.
3. Release Mutex ownership. At this point, there should be no Mutex ownership.
4. Restart app.
5. Starting second app instance. If Mutex was previously released correctly and no other same app's are running (the first one may be still running but Mutex was released), I should receive Mutex ownership same way I received it first time. But for some reason, there is still ownership pending from first Launch sometimes. That's my problem.
6. If has ownership -> Step 2. Else -> Let user know that there cannot be more app instances.
7. If has ownership -> Step 3. Else -> Finishing without releasing ownership (which I don't posses).
8. Restart etc...
|
|
|
|
|
Zilo(svk) wrote: I disagree
With what?
In your app step #4 Restart app, always occurs without regard to the Mutex condition.
In my app step #4 Restart is dependent on the Mutex condition.
|
|
|
|
|
My problem is not that I'm restarting application when mutex is not owned!!! Besides that can never happens in real...
My problem is that I'm not able to (always) own mutex in the second application launch (restart) after it was properly released in first one!!!
That application is not about restarting all the time!!!! But sometimes, when it happens, it may fail for a reason a cannot understand!
|
|
|
|
|
Zilo(svk) wrote: My problem is that I'm not able to (always) own mutex in the second application launch (restart) after it was properly released in first one!!!
As I stated previously I cannot reproduce that behavior. Not with my code or yours.
|
|
|
|
|
hmm..
I can, at least on computer at work. I run exactly that code and it failed.
Let me try at home...
Edit:
I couldn't reproduce that at home either. That's not funny at all....
|
|
|
|
|
If you can't reliably reproduce the functionality if the code, what does that tell you about the quality of your solution?
|
|
|
|
|
u are killing me...
look
I have relatively simple piece of code, that should work perfectly without any problems. It's not something sophisticated. But then, I find out that it's not working so perfectly without any problems, so I try to find out why it doesn't ??? According to all information about Mutex (I read MSDN in the meanwhile) it should work the way I wrote it. So now my question is why it doesn't ? Possibly I might miss some important piece of information... or I don't know why it doesn't work. Maybe my computer at work just got crazy. Anyway, what does that tell about the quality of my solution? I tired of this all...
zilo
|
|
|
|
|
Guys,
Mutex.Close() (in Disposing sequence)
that's it. That's my missing piece of information.
now, I can RIP )
Looks like that on faster CPU's, GC or some other mechanism took care about it(Releasing mutex completely) always before instantiating new app, what my slower CPU at work didn't manage always.
I'm just curious. Did you know it all the time?
zilo
|
|
|
|
|
Nope. I never looked at your code. I read the first part of this thread, and the last part. I never knew you posted any code.
|
|
|
|
|
Hi all,
I have developed a windows application in C#, which is going to display a report and print itt automatically without intimating the user.
The report is displayed in the web browser control using XSL in a windows forms application. I would like to know how to print the report in the landscape format? The user should not be allowed to set the page options like Portrait/landscape.
Please let me know of how this can be achieved from coding
Thanks in Advance.
Thanks and Regards
Madhu
|
|
|
|
|
Hello,
I have a problem when trying to serialize the components(the components are diffrent and they are represented by an interface from that they are derived) of a list using XmlSerializer in C#. The exception message thrown when this line is executed
"XmlSerializer ser = new XmlSerializer(typeof(ISchedule))"
is "Cannot serialize interface BL.ISchedule".
I want to know if is this thing possible and should I avoid the encountered problem.
Thak you!
Lukas
|
|
|
|
|
Hi!
I don't think this is possible.
Think about it: An interface cannot be instantiated. So the XmlSerializer could somehow serialize the public members that are part of the interface, but it doesn't make much sense because there's no way back. If you only have the information concerning the interface, you cannot create an object from this.
Regards,
mav
--
Black holes are the places where God divided by 0...
|
|
|
|