Flying Emu
Flying Emu

Reputation: 430

WPF Running Function on Separate Thread

Extremely nooby question here but anyway.

I'm trying to get a function to run on a separate thread (which it works) but, I cannot receive the value being returned by the function. This is in WPF VB.Net btw.

My codes below, I've tested that the function is returning a proper value but the MsgBox is displaying a blank. I understand you simply cannot place the slab (as I've done) into a messagebox and expect a result but I'm really stuck and have no idea how to get results.

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        MsgBox(Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Function() Pathway1A("exit"))))
    End Sub

Thanks in advance for anyone who might be able to help.

Upvotes: 0

Views: 1726

Answers (2)

Flying Emu
Flying Emu

Reputation: 430

Found the answer (edit actually it doesn't work again for some reason)

Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Dim A As Integer
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Function() A = Pathway1A("exit")))
        Msgbox(A)
    End Sub

Upvotes: 0

AlSki
AlSki

Reputation: 6961

There are several ways to do it, the newer versions of DotNet building on the older versions to provide simpler functionality and syntax.

First you can start a thread and synchronize until it occurs (this example is blocking)

MyResult myResult = null;
ManualResetEvent synchronizer = new ManualResetEvent();

public void Caller()
{
  new Thread(new ThreadStart(CalculateResult)).Start();
  synchronizer.WaitOne();
  DoSomethingWith(myResult);
}

public void CalculateResult()
{      
  myResult = ResultOfSomethingThatTakesAWhile();

  synchronizer.Set();
}

Or you can use a BackgroundWorker from DotNet 2.0

MyResult myResult = null;
var worker = new BackgroundWorker();
worker.DoWork += (Action)(()=> { myResult = ResultOfSomethingThatTakesAWhile();});
worker.RunWorkerCompleted += (Action)(()=> DoSomethingWith(myResult));

With the TPL in DotNet 4.0 you can now use Tasks (again this example is blocking)

 var t = Task.Run(() => { return ResultOfSomethingThatTakesAWhile(); });
 t.Wait();
 DoSomethingWith(t.Result);

Or you can use async with DotNet 4.5

 var myResult = await Task.Run(()=> ResultOfSomethingThatTakesAWhile());
 DoSomethingWith(myResult);

And finally if you don't really care about returning a result back to the original thread and simply want to get the processing of a result onto the UIThread, then you can use any of these methods to call onto a new Thread, and then call

Dispatcher.Invoke(()=> DoSomethingWith(myResult));

or

WinFormsControl.Invoke(()=> DoSomethingWith(myResult));

Upvotes: 2

Related Questions