How to make Dispatcher.BeginInvoke run in backgrou

2019-02-20 11:05发布

问题:

I need to run some part of application in background and allow user to update the UI while the sub is running in the background. I searched and I found out that in WPF I should use Dispatcher. Problem is even when I use dispatcher still my GUI is not usable till the all subs will finish. I attached a code here so you can have better perspective of what I mean. For example in this code when a user run the application, system should run a new thread that will change the text of first textbox while use can update the text of the second textbox. I am wondering if I am doing this right or not. Can anybody help me with this?

<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:testDispacher"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<Grid>
    <StackPanel>
        <TextBlock>UCtextbox:</TextBlock>
        <src:ToBeRunByDispacherUC x:Name="UC1" />
        <TextBlock>Windowstxtbox:</TextBlock>
        <TextBox x:Name="txtBox2" Width="100" Height="30"/>
    </StackPanel>
</Grid>

Class Window1 
Delegate Sub runSub()
Dim setTxt As runSub
Public Sub New()
    InitializeComponent()
    setTxt = AddressOf UC1.setTxtBox
End Sub
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    UC1.IsEnabled = False
    Dispatcher.Invoke(setTxt, Windows.Threading.DispatcherPriority.Background)
End Sub

End Class

<UserControl x:Class="ToBeRunByDispacherUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
    <TextBox x:Name="txtBox1" Width="100" Height="30"/>
</Grid>

Partial Public Class ToBeRunByDispacherUC

Public Sub setTxtBox()
    Dim j As Integer = 0
    For i As Integer = 0 To 10
        j += 1
        System.Threading.Thread.Sleep(1000)
    Next
    txtBox1.Text = "End"
    Me.IsEnabled = True
 End Sub
End Class

回答1:

The dispatcher should be used to update UI objects from a separate thread, it does not actually spawn up the thread for you. If you are using .NET 4.0 or higher, you can use the TPL library to spawn your thread, do your work, then update your UI object via the dispatcher from the background thread.

Task.Factory.StartNew(Sub() DoBackgroundWork())

Then, inside DoBackgroundWork whenever you want to update your UI...

Dispatcher.BeginInvoke(Sub() txtBox1.Text = "End")



回答2:

you can call to the general application.

Application.Current.Dispatcher.Invoke()