-1

Someone asked for a much clear post. I am trying to update my UI from Update function which is on my main thread. I tried to make it by using delegate but it did not work. My subscribers are sometimes called from a secondary thread and sometimes from the main thread, how can I solve this? What I have in my update function will cause lots of problems.

private void Update()
{
    if (update != null)
    {
        lock (update)
        {
            update.Invoke(oldState, state);
            update = null;
        }
    }
}

private void LoginSubscirber(AppState oldState, AppState state)
{
    lock (state)
    {
        if (oldState.loginState != state.loginState)
        {
            if (state.loginState == loginStateEnum.loadingLogin)
            {
                update = LoadingLoginCallback;
            }
            else if (state.loginState == loginStateEnum.successLogin)
            {
                update = LoginSuccescCallback;
            }
        }
    }
}

LoginSubscrirber (ignore my miss spelling of it) is called sometimes with Task.Factory.StartNew()

Paulo Morgado
  • 14,111
  • 3
  • 31
  • 59
  • There are thousands of "how to update UI from other thread in {your_favorite_framework}"... like https://stackoverflow.com/questions/2367718/automating-the-invokerequired-code-pattern for WPF... Your question is likely duplicate of some of them... – Alexei Levenkov Aug 31 '19 at 05:48

2 Answers2

0

I ended up using this aproach after searching more on thread safe. I hope it will works well in all scenarios:

ConcurrentQueue<MethodToExecute> threadSafeQueue = new ConcurrentQueue<MethodToExecute>();

    private void Update()
    {
        if (threadSafeQueue.Count > 0)
        {
            MethodToExecute changeUI;
            threadSafeQueue.TryDequeue(out changeUI);
            changeUI.action(changeUI.oldState, changeUI.state);
        }
    }

    private void Start()
    {
        StoreCreator.GetInstance.store.Subscribe += LoginSubscirber;
    }

    private void LoginSubscirber(AppState oldState, AppState state)
    {
        lock (state)
        {
            if (oldState.loginState != state.loginState)
            {
                if (state.loginState == loginStateEnum.loadingLogin)
                {
                    threadSafeQueue.Enqueue(new MethodToExecute(LoadingLoginCallback, oldState, state));
                }
                else if (state.loginState == loginStateEnum.successLogin)
                {
                    threadSafeQueue.Enqueue(new MethodToExecute(LoginSuccescCallback, oldState, state));
                }
                else if (state.loginState == loginStateEnum.failLogin)
                {
                    threadSafeQueue.Enqueue(new MethodToExecute(LoginFailCallback, oldState, state));
                }
                /*lock (oldState)
                {
                    this.oldState = oldState;
                    this.state = state;
                }*/
            }
        }
    }
0

You can use this:

var mDel = (RoutedEventHandler)delegate { clicked(a2, null); };

bxBox[z].Click += mDel ;

 ...

bxBox[z].Click -= mDel ;
Mojtaba Nava
  • 858
  • 7
  • 17