gpt4 book ai didi

c# - UnityMainThreadDispatcher 是做什么的?

转载 作者:行者123 更新时间:2023-12-03 12:44:07 34 4
gpt4 key购买 nike

我读了这段代码。

https://github.com/johnjcsmith/iPhoneMoCapUnity/blob/master/Assets/NetworkMeshAnimator.cs

在代码的第 62 行附近有以下描述。

这是在做什么处理?

    if (UnityMainThreadDispatcher.Exists()) {
dispatcher = UnityMainThreadDispatcher.Instance ();
}

GitHub上有代码,但它是Unity的标准功能吗?

最佳答案

这就是为什么您需要在 Unity 中使用伪调度程序:

在 Unity 中,大多数对象只能在 Unity 主线程中创建。

但是假设您有一些繁重的任务想要在后台运行,例如 Task.Run ,在您的任务中,您将无法实例化上述对象,但仍想实例化。

解决这个问题有很多解决方案,但它们都利用相同的东西:

Capturing Unity's synchronization context and posting messages to it



这是一个原始的方法,灵感来自 Raymond Chen 的旧新事物:

C++/WinRT envy: Bringing thread switching tasks to C# (WPF and WinForms edition)

概念如下:在方法中随时切换到特定线程!

公共(public)类型

线程切换器:
using System.Runtime.CompilerServices;
using JetBrains.Annotations;

namespace Threading
{
/// <summary>
/// Defines an object that switches to a thread.
/// </summary>
[PublicAPI]
public interface IThreadSwitcher : INotifyCompletion
{
bool IsCompleted { get; }

IThreadSwitcher GetAwaiter();

void GetResult();
}
}

线程切换器:
using Threading.Internal;

namespace Threading
{
/// <summary>
/// Switches to a particular thread.
/// </summary>
public static class ThreadSwitcher
{
/// <summary>
/// Switches to the Task thread.
/// </summary>
/// <returns></returns>
public static IThreadSwitcher ResumeTaskAsync()
{
return new ThreadSwitcherTask();
}

/// <summary>
/// Switch to the Unity thread.
/// </summary>
/// <returns></returns>
public static IThreadSwitcher ResumeUnityAsync()
{
return new ThreadSwitcherUnity();
}
}
}

私有(private)类型

线程切换任务:
using System;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;

namespace Threading.Internal
{
internal struct ThreadSwitcherTask : IThreadSwitcher
{
public IThreadSwitcher GetAwaiter()
{
return this;
}

public bool IsCompleted => SynchronizationContext.Current == null;

public void GetResult()
{
}

public void OnCompleted([NotNull] Action continuation)
{
if (continuation == null)
throw new ArgumentNullException(nameof(continuation));

Task.Run(continuation);
}
}
}

线程切换器统一:
using System;
using System.Threading;
using JetBrains.Annotations;

namespace Threading.Internal
{
internal struct ThreadSwitcherUnity : IThreadSwitcher
{
public IThreadSwitcher GetAwaiter()
{
return this;
}

public bool IsCompleted => SynchronizationContext.Current == UnityThread.Context;

public void GetResult()
{
}

public void OnCompleted([NotNull] Action continuation)
{
if (continuation == null)
throw new ArgumentNullException(nameof(continuation));

UnityThread.Context.Post(s => continuation(), null);
}
}
}

统一线程:
using System.Threading;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;

#endif

namespace Threading.Internal
{
internal static class UnityThread
{
#pragma warning disable IDE0032 // Use auto property
private static SynchronizationContext _context;
#pragma warning restore IDE0032 // Use auto property

public static SynchronizationContext Context => _context;

#if UNITY_EDITOR
[InitializeOnLoadMethod]
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Capture()
{
_context = SynchronizationContext.Current;
}
}
}

示例

尽管它是一种奇特的方法,但它具有巨大的优势,即通过使用单个调用,您可以在同一方法中的不同线程中工作。以下代码使用 Task.Run 执行但在实例化 Unity 对象时不会产生任何错误,因为它是在正确的线程中完成的。
private static async Task DoWork(CancellationToken token)
{
token.ThrowIfCancellationRequested();

var gameObjects = new List<GameObject>();

await ThreadSwitcher.ResumeUnityAsync();

for (var i = 0; i < 25; i++)
{
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();

await Task.Delay(125, token);

var gameObject = new GameObject(i.ToString());

gameObjects.Add(gameObject);
}
}

现在由您来对您的工作进行精分割割,因为 Unity 同步上下文本质上并不意味着运行繁重的计算,而是仅实例化您无法从另一个线程执行的内容。

一个简单的例子是生成一些程序网格:
  • 在你的任务中做所有的数学运算并产生足够的数据来创建一个网格
  • 即顶点、法线、颜色、uvs
  • 切换到 Unity 线程
  • 从这些数据中创建一个网格,PERIOD,这将足够快以至于无法察觉

  • 这是一个有趣的问题,我希望我已经回答了!

    关于c# - UnityMainThreadDispatcher 是做什么的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58469468/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com