简体   繁体   中英

Invoking Method on UI thread from within a Lock() with .Net 4.0

I have the same problem as this person had . However the question was answered by using .Net 4.5, but I only have .Net 4.0.

So I created my own asynchronous semaphore based on this tutorial and implemented my code based on additional comments of the guy that posted the anwer:

private void Foo()
{
    try
    {
        Semaphore.WaitAsync().ContinueWith(previousTask =>
        {
            if (Dispatcher.FromThread(Thread.CurrentThread) != null)
            {
                Bar();
            }
            else
            {
                Application.Current.Dispatcher.Invoke(new Action(() => Bar()));
            }
        });
    }
    finally
    {
        Semaphore.Release();
    }
}

This does not work for me though, Bar is called in parallel.

You're releasing the semaphore too early. Release it in the ContinueWith handler at the end.

Are you aware that Foo() will return immediately regardless of then the synchronized code actually runs?

The if (Dispatcher.FromThread(Thread.CurrentThread) != null) also is highly suspicious. You should know whether you need to marshal or not.

Since continuations can be inlined it is hard to predict on what thread it actually runs. This is quite nasty non-determinism in the TPL. You probably should specify the UI task scheduler for that continuation. That way you never need to marshal.

Also note, that you can use await on .NET 4.0 so maybe this question is moot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM