Unity - A计划(永久有效期) 扫二维码继续学习 二维码时效为半小时

(197评价)
价格: 4431.00元
Unity 中C#线程调用主线程方法的问题
LifeChanges发起了问答2017-09-26
4
回复
3281
浏览

siki老师您好,我现在遇到网络接收的线程不能直接调用主线程的方法,比如 CancelInvoke、 SceneManager.LoadSceneAsync这些等等,希望老师帮忙讲下这种需求怎么设计能解决而且执行效率高些并考虑到线程安全性。

所有回复
  • sdhexu 2017-09-26

    方法存存在于进程的代码区,是不区分线程的。。任何线程都可以调用任何方法。你说的不能调用,应该是因为你没有提供给线程要调用的方法所属的类的那个对象而已。

    比如:

      public class a {

            public someFunc();

      }

      static void Thread()

      {

            // 这里你想调用A里面的somfunc,你得提供一个a类的对象。

       }

    线程安全性,可以通过使用各种内核对象,比如:信号量、互斥对象、内存映射、临界区变量等等。。根据需求来。

    • LifeChanges 2017-09-26

      1.首先C#线程是不能"直接"调用Unity主线程一些方法的,你可以试试调用CancelInvoke、SceneManager.LoadSceneAsync等一些Mono方法验证下2.我现在找到方法就是把这些调用添加进事件然后在Update中按照顺序执行,代码放在下面,有需要的可以看下。

      (0) 回复
    还有-4条回复,点击查看
    你还没有登录,请先登录注册
  • LifeChanges 2017-09-26

    using System;
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;

    public class EventProcessor : MonoBehaviour {

        private static System.Object m_queueLock = new System.Object();
        private static List<Action> m_queuedEvents = new List<Action>();
        private static List<Action> m_executingEvents = new List<Action>();

        private volatile static bool noActionQueueToExecuteUpdateFunc = true;

        void Awake()
        {
            DontDestroyOnLoad (this.gameObject);
        }

        void Update() {

            if (noActionQueueToExecuteUpdateFunc)
            {
                return;
            }

            MoveQueuedEventsToExecuting();

            while (m_executingEvents.Count > 0) {
                Action e = m_executingEvents[0];
                m_executingEvents.RemoveAt(0);
                e();
            }

            noActionQueueToExecuteUpdateFunc = true;
        }

        public static void QueueEvent(Action action) {
            lock(m_queueLock) {
                m_queuedEvents.Add(action);
                noActionQueueToExecuteUpdateFunc = false;
            }
        }

        private void MoveQueuedEventsToExecuting() {
            lock(m_queueLock) {
                while (m_queuedEvents.Count > 0) {
                    Action e = m_queuedEvents[0];
                    m_executingEvents.Add(e);
                    m_queuedEvents.RemoveAt(0);
                }
            }
        }
    }

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
  • siki 2017-09-28

    这个可以参考老师在丛林战争中讲的,网络接收的线程中把接收到的数据保存下来,  Update里面在进行处理,或者是调用cancel还是其他的方法

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
发表回复
你还没有登录,请先 登录或 注册!