C# create form on separate thread from formless ap

2019-09-14 10:17发布

I'm currently creating a formless C# application that will act as a SignalR client. The goal is for the client to run silently in the background and show a form when it is triggered by SignalR.

Currently, I'm having an issue showing the GUI. Since SignalR needs to run asynchronously, and I can't have an async Main() method, I currently have to use Task.ContinueWith

static void Main()
{
    _url = "https://localhost:44300";

    var hubConnection = new HubConnection(_url);
    var hubProxy = hubConnection.CreateHubProxy("HubName");

    hubConnection.Start().ContinueWith(task =>
    {
        if (task.IsFaulted)
        {
            MessageBox.Show("There was an error opening the connection");
        }
        else
        {
            Trace.WriteLine("Connection established");
        }
    }).Wait();

    hubProxy.On("showForm", showForm);
    Application.Run();
}

This is the showForm method:

private static void ShowForm()
{
    var alertForm = new AlertForm();
    alertForm.Show();
}

This works fine at first - it connects to the hub, and calls the showForm() method when I call showForm from the server. However, the form never renders and shows as Not Responding. Calling .ShowDialog will mean the form actually renders, but the SignalR client stops listening to the hub.

So, how can I show the form such that it runs on a separate thread and doesn't block the execution of my SignalR client?

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-09-14 10:47

The problem with your code is; although you create a message loop with Application.Run in Main, hubProxy.On is executed on a different thread. Simplest solution would be running every instance of AlertForm in its own thread with its own message loop.

private static void ShowForm()
{
    var t = new Thread(() =>
    {
        var alertForm = new AlertForm();
        alertForm.Show();
        Application.Run(alertForm); //Begins running a standard application message loop on the current thread, and makes the specified form visible.
    });
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}
查看更多
登录 后发表回答