Michael Pittino
Michael Pittino

Reputation: 2178

Do work without blocking the gui thread

I have a c# windows forms application and use a library which does not provide async-await functionality.

When I press on a button I want to do some work (webrequesting). While doing this work I dont want to freeze my gui.

I tried several approaches, for example:

public static Task<bool> LoginUser(string username, string password)
{
    return Task.Factory.StartNew(() =>
    {
        try
        {
            session = new AuthenticatedSession<User>(new User(username), Cryptography.GetMd5(password));

            return true;
        }
        catch (InvalidAuthenticationException)
        {
            return false;
        }
    });
}

When I call LoginUser("foo", "bar").Result the gui freezes until the work is done (I understand that this is not async because I can't await new AuthenticatedSession<...

So I look for something like:

  1. Create a thread with a action as parameter
  2. Return the value from the thread
  3. End the thread

Upvotes: 0

Views: 505

Answers (1)

T McKeown
T McKeown

Reputation: 12847

Try forcing a new thread (or WorkerThread) instead of using the TaskFactory.

Thread t = new Thread (delegate()
{
    try
    {
        session = new AuthenticatedSession<User>(new User(username), Cryptography.GetMd5(password));
        Success();  //coded below
    }
    catch (InvalidAuthenticationException)
    {
        Fail();
    }     
});
t.Start();

Your list requires that we return a value, all we really can do is call a method or set state indicating the return value or even signal (ManualResetEventSlim) if you want some blocking, but your requirements state you want non-blocking.

To resume execution or signal the GUI that your process is done you would invoke some method on the UI thread, like this:

void Success() {
  Invoke((MethodInvoker) delegate {
    SomeMethodOnTheUI();
  });
}

This is basically an async/callback strategy.

Upvotes: 2

Related Questions