4

I am working in WPF and I have a dialog window that start a listen socket, and is supposed to close as soon as someone connect. Here is my naive, non working snippet code:

void acceptCallback(IAsyncResult iar)
{
    socket = listenSocket.EndAccept(iar);
    DialogResult = true; // error here
    Close();
}

private void ValidButton_Click(object sender, RoutedEventArgs e)
{
    IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
    listenSocket.Bind(iep);
    listenSocket.Listen(1);
    listenSocket.BeginAccept(acceptCallback, null);
}

I get an error telling me that DialogResult can't be accessed from this thread, I understand that my "acceptCallback" function is called from the thread running the accept asynchronously, but don't really know how to get the behavior I want.

How can I tell the main thread from this callback that it is supposed to close the dialog window in a proper way ?

Titan
  • 181
  • 2
  • 9

1 Answers1

6

You can usually access UI elements (as the dialog window object) only from the UI thread.

That is simply done by using the Dispatcher of the UI element:

void acceptCallback(IAsyncResult iar)
{
    socket = listenSocket.EndAccept(iar);

    Dispatcher.Invoke(() =>
    {
        DialogResult = true;
        Close();
    });
}

In case it is .NET 4.0 or below, you have to explicitly create an Action from the lambda expression:

Dispatcher.Invoke(new Action(() =>
{
    DialogResult = true;
    Close();
}));

or

Dispatcher.Invoke((Action)(() =>
{
    DialogResult = true;
    Close();
}));
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Your code is not working: Cannot convert lambda expression to type 'System.Delegate', however I completed your answer with this related question, thanks for your help, (I need to understand it now ^^). http://stackoverflow.com/questions/9549358/cannot-convert-lambda-expression-to-type-system-delegate – Titan Oct 28 '13 at 06:47