比如说现在有两个进程Pr1 和 Pr2
它们在运行过程中,如果满足某个条件,就会弹出一个标题为 xxx 的窗体。
现在启动这两个进程。如果它们在同一时间满足那个条件,就会弹出两个 xxx 窗体,这个如何实现互斥啊?
请高手解答。现在尝试过的方案:
 [DllImport("User32.dll", EntryPoint = "FindWindow")]
 private static extern int FindWindow(string lpClassName, string lpWindowName);
while(FindWindow(null, "xxx") != 0)
{
    Thread.Sleep(100);
    Application.DoEvents();
}
new xxx().ShowDialog();这样写直接卡的不成样子。尝试过Sleep(1000),Sleep(10000)。但是时间越长。同时弹出来的可能性就越大。另外
,这段在UI里面,没在线程。希望高手能指点一条明路啊~

解决方案 »

  1.   


    static void Main() 
    {
    bool bExist;
                            //判断程序是否运行
    Mutex MyMutex=new Mutex(true,"OnlyRunOncetime",out bExist);
    if(bExist)
    {
    Application.Run(new Form1());
    MyMutex.ReleaseMutex();
    }
    else
    {
    MessageBox.Show("***已经运行!","信息提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
    }
    }
      

  2.   

    Use Inter-Process semaphores.Source codes copied from: 
    A C# Framework for Interprocess Synchronization and Communication
    2.3 Inter-Process Semaphores, 
    http://www.codeproject.com/KB/threads/csthreadmsg.aspx
    [DllImport("kernel32",EntryPoint="CreateSemaphore", SetLastError=true,CharSet=CharSet.Unicode)]
    internal static extern uint CreateSemaphore( SecurityAttributes auth, int initialCount, int maximumCount, string name);[DllImport("kernel32",EntryPoint="WaitForSingleObject", SetLastError=true,CharSet=CharSet.Unicode)]
    internal static extern uint WaitForSingleObject( uint hHandle, uint dwMilliseconds );[DllImport("kernel32",EntryPoint="ReleaseSemaphore", SetLastError=true,CharSet=CharSet.Unicode)]
    [return : MarshalAs( UnmanagedType.VariantBool )]
    internal static extern bool ReleaseSemaphore( uint hHandle, int lReleaseCount, out int lpPreviousCount);
        
    [DllImport("kernel32",EntryPoint="CloseHandle",SetLastError=true, CharSet=CharSet.Unicode)]
    [return : MarshalAs( UnmanagedType.VariantBool )]
    internal static extern bool CloseHandle(uint hHandle);public class ProcessSemaphore : ISemaphore, IDisposable
    {
      private uint handle;
      private readonly uint interruptReactionTime;  public ProcessSemaphore(string name) : this( name,0,int.MaxValue,500 ) {}
      public ProcessSemaphore(string name, int initial) : this( name,initial,int.MaxValue,500) {}
      public ProcessSemaphore(string name, int initial, int max, int interruptReactionTime)
      {       
        this.interruptReactionTime = (uint)interruptReactionTime;
        this.handle = NTKernel.CreateSemaphore(null, initial, max, name);
        if(handle == 0)
          throw new SemaphoreFailedException();
      }  public void Acquire()
      {
        while(true)
        { //looped 0.5s timeout to make NT-blocked threads interruptable.      uint res = NTKernel.WaitForSingleObject(handle, interruptReactionTime);
          try 
      {
        System.Threading.Thread.Sleep(0);
      } 
          catch(System.Threading.ThreadInterruptedException e)
          {
            if(res == 0)
            { //Rollback           int previousCount;
              NTKernel.ReleaseSemaphore(handle,1,out previousCount);
            }
            throw e;
          }
          if(res == 0)
            return;
          if(res != 258)
            throw new SemaphoreFailedException();
        }
      }  public void Acquire(TimeSpan timeout)
      {
        uint milliseconds = (uint)timeout.TotalMilliseconds;
        if(NTKernel.WaitForSingleObject(handle, milliseconds) != 0)
          throw new SemaphoreFailedException();  
      }  public void Release()
      {
        int previousCount;
        if(!NTKernel.ReleaseSemaphore(handle, 1, out previousCount))
          throw new SemaphoreFailedException();  
      }  #region IDisposable Member
      public void Dispose()
      {
        if(handle != 0)
        {
          if(NTKernel.CloseHandle(handle))
            handle = 0;
        }
      }
      #endregion
    }
      

  3.   

    System.Threading.Thread.Sleep(0);//这句有什么意义啊?
      

  4.   

    Sorry, I cannot type Chinese now, we can discuss about it later. 
    I copied the source code from the web page--you can have a look, but it is in English. Semaphores in Chinese is called 信号量, maybe you can search about 进程 and 信号量 yourself."System.Threading.Thread.Sleep(0);//这句有什么意义啊?"
    //looped 0.5s timeout to [b]make NT-blocked threads interruptable.[\b]
    * 进程 and 信号量 are get from: type pin yin of the two words in Google/Baidu first, and copy the words from the results
      

  5.   

    单例  xxx 窗体 
      

  6.   

    bool hasMutex;
    System.Threading.Mutex mutex = new System.Threading.Mutex(true, "", out hasMutex);
                if (hasMutex)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new FrmMain());
                }
                else
                {
                    MessageBox.Show("程序已经运行", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Application.Exit();
                }或
    [DllImport("User32.dll")]
    public static extern void SetForegroundWindow(IntPtr hwnd);
    [DllImport("User32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
    private const int WS_SHOWNORMAL = 3;
    private static bool ExistRunningInstance()
    {
    Process currentProcess = Process.GetCurrentProcess();
    Process[] procList = Process.GetProcessesByName(currentProcess.ProcessName);
    foreach (Process proc in procList)
    {
    if (proc.Id != currentProcess.Id)
    {
    ShowWindowAsync(proc.MainWindowHandle, WS_SHOWNORMAL);
    SetForegroundWindow(proc.MainWindowHandle);return true;
    }
    }return false;
    }
    [STAThread]
    static void Main()
    {
    if (ExistRunningInstance())
    {
    Environment.Exit(1); 
    }
    }
      

  7.   

    C#中四种进程或线程同步互斥的控制方法(一)
    http://security.zdnet.com.cn/security_zone/2008/0901/1097472.shtmlC#中四种进程或线程同步互斥的控制方法(二)
    http://security.zdnet.com.cn/security_zone/2008/0901/1097477.shtml
      

  8.   


    Mutex 互斥进程可以,但是现在的情况是 进程已经有互斥了,需要互斥的是进程中的窗体,如果这个窗体的标题一样,只是在不同进程中,怎么实现互斥?请前辈赐教。还有,海风兄说的判断下有没有这个窗体,我就是这么做的啊。我根据窗口的标题取它的句柄,如果 == 0,那就不存在窗体。然后弹出来。关键是在while()中,这个Sleep()做循环体的时候,小了占很多资源,大了就有可能判断失效,而且阻塞进程UI,还弹出多个 xxx 窗体来。还有什么途径或方式么?高手们,Help Me 啊。
      

  9.   


    Mutex 互斥进程可以,但是现在的情况是 进程已经有互斥了,需要互斥的是进程中的窗体,如果这个窗体的标题一样,只是在不同进程中,怎么实现互斥?请前辈赐教。还有,海风兄说的判断下有没有这个窗体,我就是这么做的啊。我根据窗口的标题取它的句柄,如果 == 0,那就不存在窗体。然后弹出来。关键是在while()中,这个Sleep()做循环体的时候,小了占很多资源,大了就有可能判断失效,而且阻塞进程UI,还弹出多个 xxx 窗体来。还有什么途径或方式么?高手们,Help Me 啊。
      

  10.   


    Mutex 互斥进程可以,但是现在的情况是 进程已经有互斥了,需要互斥的是进程中的窗体,如果这个窗体的标题一样,只是在不同进程中,怎么实现互斥?请前辈赐教。还有,海风兄说的判断下有没有这个窗体,我就是这么做的啊。我根据窗口的标题取它的句柄,如果 == 0,那就不存在窗体。然后弹出来。关键是在while()中,这个Sleep()做循环体的时候,小了占很多资源,大了就有可能判断失效,而且阻塞进程UI,还弹出多个 xxx 窗体来。还有什么途径或方式么?高手们,Help Me 啊。
      

  11.   

    我对C++吃不来啊~不过还是谢谢了~
    海风兄又敷衍我~。谢谢如梦前辈。
    最后我是把所有的进程设立为子进程,然后从主进程请求是否允许弹xxx,所有的判断到放在主进程。这样只有一个判断,就解决问题了。就是有点麻烦。可能大家没弄清楚,这里如果pr1的xxx弹出来了,pr2要想弹,就要等pr1的xxx关闭以后才能弹,所以用到了很费资源的递归。我就是想找一种想进程互斥Mutex 这个对象类似的能解决这个问题的方式,但是最后还是绕回去了。 谢谢大家 结贴给分