Reputation: 117
now I have this:
[STAThread]
static void Main()
{
if (flag) //client view
Application.Run(new Main_Menu());
else
{
Application.Run(new ServerForm());
}
}
ServerForm.cs
public partial class ServerForm : Form
{
public ServerForm()
{
InitializeComponent();
BeginListening(logBox);
}
public void addLog(string msg)
{
this.logBox.Items.Add(msg);
}
private void button1_Click(object sender, EventArgs e)
{
}
private async void BeginListening(ListBox lv)
{
Server s = new Server(lv);
s.Start();
}
}
Server.cs
public class Server
{
ManualResetEvent allDone = new ManualResetEvent(false);
ListBox logs;
///
///
/// Starts a server that listens to connections
///
public Server(ListBox lb)
{
logs = lb;
}
public void Start()
{
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Loopback, 1440));
while (true)
{
Console.Out.WriteLine("Waiting for connection...");
allDone.Reset();
listener.Listen(100);
listener.BeginAccept(Accept, listener);
allDone.WaitOne(); //halts this thread
}
}
//other methods like Send, Receive etc.
}
I would like to run my ServerForm
( it has ListBox to print msg from Server
). I know ListBox
argument will not work, but I could not run Server
inifinite loop without suspend ServerForm
( I could not even move window). I tried it also with Threads - unfortunately it does not work to.
Upvotes: 2
Views: 3345
Reputation: 101150
WinForms have something called a UI-thread. Its a thread which is responsible of drawing and handling the UI. If that thread is busy doing something, the UI will stop respond.
The regular socket methods are blocking. That means that they do not return control to your application unless something have happened on the socket. Thus, each time you do a socket operation on the UI thread, the UI will stop responding until the socket method completes.
To get around that, you need to create a separate thread for the socket operations.
public class Server
{
ManualResetEvent allDone = new ManualResetEvent(false);
Thread _socketThread;
ListBox logs;
public Server(ListBox lb)
{
logs = lb;
}
public void Start()
{
_socketThread = new Thread(SocketThreadFunc);
_socketThread.Start();
}
public void SocketThreadFunc(object state)
{
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Loopback, 1440));
while (true)
{
Console.Out.WriteLine("Waiting for connection...");
allDone.Reset();
listener.Listen(100);
listener.BeginAccept(Accept, listener);
allDone.WaitOne(); //halts this thread
}
}
//other methods like Send, Receive etc.
}
However, all UI operations MUST take place on the UI thread. This, if you try to update the listbox
from the socket thread you will get an exception.
The easiest way to solve that is to use Invoke.
Upvotes: 3