Я создал приложение для извлечения данных с клиента с использованием асинхронного программирования сокетов. Пользователь может видеть приложение как значок в 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;
}
}
Я подозревавший это может быть проблемой, многопоточность, но я новичок в программировании и не может точно определить. Любые выводы о том, как решить эту проблему, очень ценятся.
Поскольку вы хотели, чтобы закрыть приложение, вам не нужно, чтобы закрыть форму, и вы должны предоставить код, показывающий, как использовать ManualResetEvent allDone. –
Я проверил снятие сокетной части, затем работает отлично. Полагаю, это часть потока, которая является причиной. Я попытался закрыть/сбросить поток AllDo в menuItem1_Click, но он не имеет никакого эффекта. – Meenakshi