user1763295
user1763295

Reputation: 1088

C# Threading with functions that return variables

Okay so basically I have a function that returns a string, but to get that string it uses webrequest which means while it's doing that webrequest the form is locking up unless I put it in a different thread.

But I can't figure out a way to capture the returned data in a thread since it's started using thread.start and that's a void.

Any help please?

Current code if it matters to anyone:

string CreateReqThread(string UrlReq)
{
    System.Threading.Thread NewThread = new System.Threading.Thread(() => CreateReq(UrlReq));
    string ReturnedData = "";
    return ReturnedData;
}

string CreateReq(string url)
{
    try
    {
        WebRequest SendReq = WebRequest.Create(url);

        SendReq.Credentials = CredentialCache.DefaultCredentials;
        SendReq.Proxy = WebRequest.DefaultWebProxy;                 //For closed port networks like colleges
        SendReq.Proxy.Credentials = CredentialCache.DefaultCredentials;
        SendReq.Timeout = 15000;

        System.IO.StreamReader Reader = new System.IO.StreamReader(SendReq.GetResponse().GetResponseStream());
        string Response = Reader.ReadToEnd();
        Reader.Close();
        return Response;
    }
    catch (WebException e)
    {
        EBox(e.Message, "Unknown Error While Connecting");
        return null;
    }
}

Upvotes: 2

Views: 320

Answers (1)

Reed Copsey
Reed Copsey

Reputation: 564413

A common means of doing this is to use a Task<T> instead of a thread:

Task<string> CreateReqThread(string UrlReq)
{
    return Task.Factory.StartNew() => CreateReq(UrlReq));

    // In .NET 4.5, you can use (or better yet, reimplement using await/async directly)
    // return Task.Run(() => CreateReq(UrlReq));
}

You can then call Task<T>.Result to get the returned value (later), when it's needed, or schedule a continuation on the task which will run when it completes.

This could look something like:

var request = CreateReqThread(theUri);
request.ContinueWith(t =>
{
     // Shove results in a text box
     this.textBox.Text = t.Result;
}, TaskScheduler.FromCurrentSynchronizationContext());

This also works perfectly with the new await/async support in C# 5.

Upvotes: 3

Related Questions