В .NET есть понятие, называемое SynchronizationContext .
Вкратце контекст синхронизации может делегировать работу тому потоку, с которым он связан (в зависимости от структуры это может быть пул потоков , поток GUI , поток, который создал контекст синхронизации ... и т. Д.).
Использование чего-то подобного должно делать эту работу:
private void LoadTextureImage(string imagePath)
{
var syncContext = SynchronizationContext.Current;
OnBytesLoaded callback = new OnBytesLoaded(bytes => syncContext .Post(_ => LoadBytesToTexture(bytes), null));
System.Threading.ThreadPool.QueueUserWorkItem(o =>
{
byte[] bytes = System.IO.File.ReadAllBytes(imagePath);
Debug.Log($"Loaded image bytes");
callback?.Invoke(bytes);
});
}
ПРИМЕЧАНИЕ:
SynchronizationContext
зависит от контекста вызова.
В текущем сценарии syncContext
в захваченном при закрытии bytes => syncContext.Post
, таким образом
свойство. Current
вернет syncContext
, делегируя работу обратно в поток GUI (потому что LoadTextureImage
вызывается из потока GUI ),
в противном случае, если мы использовали bytes => SynchronizationContext.Current.Post
, это может привести к null или syncContext
, что делегирует работу обратнов ThreadPool (потому что. Current
вызывается из потока в пуле).
Запрошена дополнительная информация из комментариев о:
OnBytesLoaded(bytes => syncContext .Post(_ => LoadBytesToTexture(bytes), null))
Этот
OnBytesLoaded callback = new OnBytesLoaded(LoadBytesToTexture);
совпадает с
OnBytesLoaded callback = new OnBytesLoaded(bytes => LoadBytesToTexture(bytes));
В исходной версии кода вы использовали LoadBytesToTexture
в качестве делегата для OnBytesLoaded
(который ожидает метод / делегат со следующим определением byte [] -> void )Теперь мы передаем новый делегат, который будет использовать syncContext
для постановки в очередь LoadBytesToTexture
обратно в поток GUI, который снова имеет то же определение bytes [] -> void.
Вместо прямого вызоваLoadBytesToTexture
, мы говорим syncContext
поставить в очередь LoadBytesToTexture
обратно в поток GUI с использованием байтов, переданных в этом вызове callback?.Invoke(bytes)
.