C# 与Windows窗体应用程序上的NotifyIcon关联的上下文菜单的菜单项上的单击事件未启动,但需要再次单击图标才能工作
我制作了一个应用程序,使用异步套接字编程从客户端获取数据。 用户可以在tasktray中将应用程序视为图标,并可以使用“关闭”应用程序 右键单击托盘图标上的菜单。 为此,我编写了一个Windows窗体应用程序,使窗体不可见,并关联了一个可见的notifyicon 总是。在notifyicon中,添加了一个contextmenu,并向用户显示一个“close”选项作为contextmenu菜单项 右键单击托盘图标时,上下文菜单显示良好。 但是,当单击contextmenu的menuitem时,应用程序不会关闭 编码。它需要在托盘图标上再右键单击一次(单击关闭选项后),然后关闭所有资源。 请参阅以下相关代码:C# 与Windows窗体应用程序上的NotifyIcon关联的上下文菜单的菜单项上的单击事件未启动,但需要再次单击图标才能工作,c#,winforms,contextmenu,menuitem,C#,Winforms,Contextmenu,Menuitem,我制作了一个应用程序,使用异步套接字编程从客户端获取数据。 用户可以在tasktray中将应用程序视为图标,并可以使用“关闭”应用程序 右键单击托盘图标上的菜单。 为此,我编写了一个Windows窗体应用程序,使窗体不可见,并关联了一个可见的notifyicon 总是。在notifyicon中,添加了一个contextmenu,并向用户显示一个“close”选项作为contextmenu菜单项 右键单击托盘图标时,上下文菜单显示良好。 但是,当单击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;
}
}
我怀疑这可能是一个多线程问题,但我对编程还不熟悉,不能准确指出。非常感谢关于如何解决此问题的任何线索。下面的代码可以很好地解决此问题
private void menuItem1_Click(Object sender, System.EventArgs e)
{
Application.ExitThread();
}
谢谢你的评论。它仍然关闭后,再次点击托盘图标为我。实际上,在单击关闭后,只需单击托盘图标即可触发函数。一旦触发事件,应用程序将退出当前线程上的消息循环并关闭线程上的所有窗口。在design中创建菜单项并检查它。是的,它可以工作。对于套接字部分,它显示了这种行为,所以我现在检查线程功能。虽然我不确定需要什么,但在菜单中关闭或重置它1\u单击没有帮助。由于您打算关闭应用程序,您不需要关闭表单,并且您应该提供显示如何使用ManualResetEvent allDone的代码。我检查了移除插座部分,关闭效果很好。所以,我想,是螺纹部分造成的。我试图在菜单项下关闭/重置AllDo线程,但没有效果。