c#简单的Web服务器,在接收请求时启动表单

时间:2014-01-29 15:51:02

标签: c# multithreading winforms webserver

我有一个C#应用程序,它只充当本地计算机的Web服务器。 我使用this site中的示例作为我的Web服务器的基础。

所以,这是我的问题,主应用程序产生一个监听器线程来监听和处理响应。

在Program.cs中

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.Run(new SysTrayApp());
    }
}

在SysTrayApp.cs中:

public partial class SysTrayApp : Form
{
    ...
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        WebServer myWebServer = new WebServer(WebServer.Response, "http://localhost:8080/");
        myWebServer.Run();
    }
}

在WebServer.cs中

...
public void Run()
{
    ThreadPool.QueueUserWorkItem((o) =>
    {
        Console.WriteLine("Webserver running...");
        try
        {
            while (_listener.IsListening)
            {
                var ctx = _listener.GetContext();
                try
                {
                    string rstr = _responderMethod(ctx.Request);
                    byte[] buf = Encoding.UTF8.GetBytes(rstr);
                    ctx.Response.ContentLength64 = buf.Length;
                    ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                }
                catch { } // suppress any exceptions
                finally
                {
                    // always close the stream
                    ctx.Response.OutputStream.Close();
                }
            }
        }
        catch { } // suppress any exceptions
    });
}

收到请求时,我想将Windows窗体显示到本地环境(而不是HTTP响应)。问题是当我收到请求时我不再在主要的STAThread中,所以我无法正确打开表单。

如果我尝试在侦听器线程中打开它,表单就会冻结,因为侦听器开始侦听并阻塞线程。如果我打开一个线程池线程,就会发生类似的事情。

public static string Response(HttpListenerRequest request)
{

    Form form = new Form();
    form.Show();

    return "TEST!";
}

如果我在一个新的普通线程中打开它,表格会弹出,然后线程关闭,然后表格再次关闭。

public static string Response(HttpListenerRequest request)
{
    Thread thread = new Thread(startForm);
    thread.Start();
    return "TEST!";
}

public static void startForm()
{
    Form form = new Form();
    form.Show();
}

因此,从我可以看出,只有主应用程序/ UI线程中的表单似乎正常工作,而且,您不能阻止主线程,否则表单冻结。因此,从WebServer侦听器中,如何在主线程上触发表单的打开? 我应该在主窗体上创建一个启动第二个窗体并尝试从监听器线程触发它的事件吗?

或者有更好的方法吗?

P.S。我是一个PHP / Python程序员,不得不冒险进入C#只是为了一个项目,所以我不确定我在做什么。

1 个答案:

答案 0 :(得分:2)

您可以在工作线程中调用方法

,如下所示

SysTrayApp

BTW:不要使用线程池中的线程来执行长时间运行的任务。 Why .net Threadpool is used only for short time span tasks?