2016-02-03 20 views
3

我已經創建了一個應用程序,使用異步套接字編程從客戶端獲取數據。 用戶可以在任務欄中將該應用程序視爲圖標,並可通過在托盤圖標上使用右鍵菜單 「關閉」應用程序。 要做到這一點,我寫了一個Windows窗體應用程序,使形式不可見,關聯一個notifyicon,它始終可見 。在notifyicon添加一個contextmenu並顯示一個'關閉'選項作爲一個contextmenu菜單項給用戶。在Windows窗體應用程序上與NotifyIcon關聯的ContextMenu的MenuItem上的點擊事件不會觸發,但需要再次點擊圖標才能工作

在右鍵單擊托盤圖標時,右鍵菜單顯示正常。 但是,當點擊contextmenu的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

我檢查刪除插座部分,接近完美的作品。所以這是線索的一部分,我猜是這是原因。我嘗試關閉/重置menuItem1_Click中的AllDo線程,但它沒有效果。 – Meenakshi

回答

1

既然你打算關閉該應用程序它工作正常,這個下面的代碼

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

感謝您的評論。它還會在我再次點擊托盤圖標後關閉。實際上,單擊關閉後,只需單擊托盤圖標即可觸發該功能。 – Meenakshi

+0

一旦事件被觸發,Application.ExitThread()退出當前線程上的消息循環並關閉線程上的所有窗口。 – Raki

+0

在設計本身創建菜單項並檢查它。 – Raki

相關問題