2016-02-03 2 views
3

Я создал приложение для извлечения данных с клиента с использованием асинхронного программирования сокетов. Пользователь может видеть приложение как значок в tasktray и может «закрыть» приложение с помощью правой кнопкой мыши на значке в трее. Чтобы сделать это, я написал приложение для форм Windows, которое было создано невидимым, связанным с ним неизвестным . В notifyicon добавлен контекстменю и отображает параметр «закрыть» в качестве контекстного меню для пользователя.Событие Click on MenuItem of ContextMenu, связанное с NotifyIcon в приложении формы Windows, не работает, но требует еще один щелчок на значке для работы

В контекстном меню отображается значок правой кнопкой мыши на значке в трее. Но когда щелкнут menuitem контекстного меню, приложение не закрывается как . Для этого требуется еще один щелчок правой кнопкой мыши по значку в трее (после нажатия кнопки «закрыть»), который затем закрывает все ресурсы. Пожалуйста, найдите соответствующий код, как недо-

public partial class Form1 : Form 
{ 
    private ContextMenu m_menu; 
    public static ManualResetEvent allDone = new ManualResetEvent(false); 
    public Form1() 
    { 
     InitializeComponent(); 
     m_menu = new ContextMenu(); 
     m_menu.MenuItems.Add(0, new MenuItem("Close", new System.EventHandler(menuItem1_Click))); 
     notifyIcon1.ContextMenu =this.m_menu; 
     notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick); 
     // Initiate listening for sockets 
     StartListening(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 

    // State object for reading client data asynchronously 
    public class StateObject 
    { 
     // Client socket, size of receive buffer, receive buffer and received data string. 
     public Socket workSocket = null; 
     public const int BufferSize = 1024; 
     public byte[] buffer = new byte[BufferSize]; 
     public StringBuilder sb = new StringBuilder(); 
    } 

    // socket program goes here, with msdn AcceptCallback and ReceiveCallback 

    public static void StartListening() 
    {    // Create a TCP/IP socket. 
      string port = ConfigurationManager.AppSettings["port"]; 
      IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt32(port)); 
      Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

     // Bind the socket to the local endpoint and listen for incoming connections. 
     try 
      { 
       listener.Bind(localEndPoint); 
       listener.Listen(1); 

      while (true) 
       { 
        // Set the event to nonsignaled state. 
        allDone.Reset(); 
        // Start an asynchronous socket to listen for connections. 
        listener.BeginAccept(new AsyncCallback(AcceptCallback),listener); 
        // Wait until a connection is made before continuing. 
        allDone.WaitOne(); 
       } 
      } 
      catch (Exception ex) 
      { 
     } 
    } 

     // AsyncResult tells status of asynchronous operation 
    private static void AcceptCallback(IAsyncResult AR) 
    { 
      // Signal the main thread to continue. 
      allDone.Set(); 
      // handler is the socket to accept incoming connection and create socket to handle remote host communications 
      // Get the socket that handles the client request. 
      Socket listener = (Socket)AR.AsyncState; 
      Socket handler = listener.EndAccept(AR); 
      // Create the state object. 
      StateObject state = new StateObject(); 
      state.workSocket = handler; 
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
       new AsyncCallback(ReceiveCallback), state); 
    } 


    private void menuItem1_Click(Object sender, System.EventArgs e) 
    { 
     this.Close(); 
     // Application.Exit(); 
     Environment.Exit(0); 
    } 

    private void notifyIcon1_DoubleClick(object sender, EventArgs e) 
    { 
     Show(); 
     ShowInTaskbar = true; 
    } 
} 

Я подозревавший это может быть проблемой, многопоточность, но я новичок в программировании и не может точно определить. Любые выводы о том, как решить эту проблему, очень ценятся.

+0

Поскольку вы хотели, чтобы закрыть приложение, вам не нужно, чтобы закрыть форму, и вы должны предоставить код, показывающий, как использовать ManualResetEvent allDone. –

+0

Я проверил снятие сокетной части, затем работает отлично. Полагаю, это часть потока, которая является причиной. Я попытался закрыть/сбросить поток AllDo в menuItem1_Click, но он не имеет никакого эффекта. – Meenakshi

ответ

1

Он отлично работает с этим ниже код

private void menuItem1_Click(Object sender, System.EventArgs e) 
    { 
    Application.ExitThread(); 
    } 
+0

Благодарим вас за комментарий. Он по-прежнему закрывается после еще одного щелчка на значке в трее для меня. Эффективно выглядит, что функция запускается одним щелчком мыши по значку в трее после нажатия кнопки закрытия. – Meenakshi

+0

Ну, как только событие запускается Application.ExitThread() Выход из цикла сообщений в текущем потоке и закрытие всех окон в потоке. – Raki

+0

Создайте пункт меню в самом дизайне и проверьте его. – Raki

 Смежные вопросы

  • Нет связанных вопросов^_^