The t.Result will block the calling thread until the Task completes. You can achieve the result you want by using the async/await keyword in conjunction with your WCF call.
private void button1_Click(object sender, EventArgs e)
{
CallGetDataAsync(17);
MessageBox.Show("inb4");
}
private async void CallGetDataAsync(int number)
{
string result = null;
var client = new Service1Client();
try
{
// After this line, control is returned to the calling method; the ConfigureAwait(true)
// explicitly indicates that when execution resumes, it should attempt to marshall back
// to the calling thread. If you change it to false, you can see that the subsequent
// messagebox does not stop you from interacting with your main form.
result = await client.GetDataAsync(number).ConfigureAwait(true);
// when the async service call completes, execution will resume here
client.Close();
}
catch
{
try
{
client.Close();
}
catch
{
client.Abort();
}
throw;
}
// display the MessageBox, this should block the UI thread
MessageBox.Show(result);
}
Running this against a service running on the same machine as the client, it is hard to see what is going on because the WCF service call will return fast enough that your "inb4" is still displayed after service result message. Putting a delay in the sample service method helps to illustrate the behavior better.
public string GetData(int value)
{
return Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith(_ => string.Format("You entered: {0}", value)).Result;
}
To your last question, a MessageBox can be invoked by a background thread. However, it won't act as a modal and block your main form if done so.