1

I have a custom WPF control that I want to show when a button is clicked and hide when processing is finished, I am trying this but the control is not visible until the processing is done.

public delegate void UpdateTextCallback(string message);

private void UpdateText(string message)
{
    if (message == "v")
        crclLoading.Visibility = Visibility.Visible;
    else
        crclLoading.Visibility = Visibility.Hidden;
}

private void TestThread()
{
    crclLoading.Dispatcher.Invoke(
        new UpdateTextCallback(this.UpdateText),
        new object[] {"v" }
    );
}

private void TestThread2()
{
    crclLoading.Dispatcher.Invoke(
        new UpdateTextCallback(this.UpdateText),
        new object[] { "s" }
    );
}

and in butoon_click:

Thread show= new Thread(new ThreadStart(TestThread));
show.Start();
//long time conusming processing
Thread hide= new Thread(new ThreadStart(TestThread2));
hide.Start();
0

2 Answers 2

2

All you do on your background threads is to call Dispatcher.Invoke and this executes the specified delegate synchronously on the UI thread.

Also, you start second thread right after you have started the first one and your code doesn't make much sense at all.

You need to actually perform some potentially long-running operation on the background thread.

By the way, the recommended way to execute something on a background thread is to start a new Task nowadays. Try this:

crclLoading.Visibility = Visibility.Visible;
Task.Factory.StartNew(()=> 
{
    //do something that might take a while here....
    System.Threading.Thread.Sleep(5000);
}).ContinueWith(task => 
{
//and then set the Visibility to Hidden once the task has finished
crclLoading.Visibility = Visibility.Hidden;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
Sign up to request clarification or add additional context in comments.

7 Comments

by //processing I wanted to say that I have time consuming process here
The problem is that you haven't. Check my code. I have a Thread.Sleep that simulates a long-running process. You have no long-running operation in your code.
Did you even bother to try my code sample? It will make crclLoading visible for 5 seconds.
of course I am working on it, thank you for your efforts, I will get back to you soon
can I add more explanation to your answer, please? what is the difference between running UI process in background and running computation process in background besides that running UI process on the same thread is more logical?
|
2

In WPF, only the thread that created a DispatcherObject may access that object. For example, a background thread that is spun off from the main UI thread cannot update the contents of a Button that was created on the UI thread. In order for the background thread to access the Content property of the Button, the background thread must delegate the work to the Dispatcher associated with the UI thread. This is accomplished by using either Invoke or BeginInvoke. Invoke is synchronous and BeginInvoke is asynchronous. The operation is added to the event queue of the Dispatcher at the specified DispatcherPriority. Invoke is a synchronous operation; therefore, control will not return to the calling object until after the callback returns.

use Dispatcher.Invoke(new Action(() => MethodName));

2 Comments

How does this relate to the question...?
"but the control is not visible until the processing is done...". That's because all code is being run on the UI thread. Dispatcher.Invoke certainly doesn't change this fact...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.