public BlendFarmManager(string file, string version, string sessionID = null, string localDir = "LocalBlendFiles")
        {
            _localDir = localDir;
            Directory.CreateDirectory(localDir);
            BlendFarmFileSession session = GetOrCreateSession(file);

            //BlendFile = file;
            //LocalBlendFile = Path.GetFullPath(Path.Combine(localDir, sessionID + ".blend"));
            Version = version;
            //SessionID = sessionID ?? Guid.NewGuid().ToString();
            SelectedSessionID = session.SessionID;
            UpdateFileVersion(session, false);
        }
        /// <summary>
        /// Creates a RenderTask for the currently connected nodes, not yet executed
        /// </summary>
        public RenderTask GetRenderTask(string file, RenderManagerSettings settings = null, Action <RenderSubTask, Bitmap> onResultUpdated = null, Action <RenderSubTask, Bitmap> onTileReceived = null)
        {
            BlendFarmFileSession session = GetOrCreateSession(file);

            CurrentTask = new RenderTask(Nodes.ToList(), session.SessionID, Version, session.FileID, settings);

            if (onResultUpdated != null)
            {
                CurrentTask.OnResultUpdated += onResultUpdated;
            }
            if (onTileReceived != null)
            {
                CurrentTask.OnTileProcessed += onTileReceived;
            }

            return(CurrentTask);
        }
        /// <summary>
        /// Synchronize the Blend file with a network path with all connected nodes
        /// </summary>
        public async Task Sync(string localPath, string windowsPath, string linuxPath, string macOSPath)
        {
            try
            {
                BlendFarmFileSession session = GetOrCreateSession(localPath);

                UpdateFileVersion(session, true);

                Syncing = true;

                long id = session.FileID;

                await Task.WhenAll(Nodes.ToList().Select(async node =>
                {
                    SyncResponse resp = null;
                    try
                    {
                        resp = await node.SyncNetworkFile(session.SessionID, id, windowsPath, linuxPath, macOSPath);
                    }
                    catch (Exception ex)
                    {
                        node.UpdateException(ex.Message);
                        return;
                    }
                    if (resp == null)
                    {
                        node.LastStatus = $"Sync Failed: No version..";
                    }
                    else
                    {
                        node.LastStatus = $"Ready";
                    }
                }).ToArray());
            }
            finally
            {
                Syncing = false;
            }
        }
        /// <summary>
        /// Updates the file version and copy it to a local directory
        /// </summary>
        public long UpdateFileVersion(BlendFarmFileSession session, bool shared)
        {
            long     oldID = session.FileID;
            FileInfo info  = new FileInfo(session.BlendFile);

            session.FileID    = info.LastWriteTime.Ticks;
            session.Networked = shared;
            if (oldID != session.FileID)
            {
                if (!shared)
                {
                    File.Copy(session.BlendFile, session.LocalBlendFile, true);
                }
                else
                {
                    File.Copy(session.BlendFile, SessionUtil.GetSessionNetworkPath(info.FullName, session.SessionID), true);
                }
                foreach (RenderNode node in Nodes)
                {
                    node.UpdateSyncedStatus(session.SessionID, false);
                }
            }
            return(session.FileID);
        }
        /// <summary>
        /// Synchronize the Blend file with all connected nodes
        /// </summary>
        public async Task Sync(string file, bool compress = false)
        {
            try
            {
                BlendFarmFileSession session = GetOrCreateSession(file);

                UpdateFileVersion(session, false);

                Syncing = true;
                //Optimize
                long id = session.FileID;

                byte[] toSend = null;
                using (MemoryStream mem = new MemoryStream())
                {
                    byte[] buffer = new byte[4096];

                    await Task.Run(() =>
                    {
                        if (compress)
                        {
                            Nodes.ToList().ForEach(x => x.UpdateActivity("Compressing.."));

                            using (FileStream str = new FileStream(session.BlendFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                                using (Stream zip = new GZipStream(mem, CompressionMode.Compress, true))
                                {
                                    int read = 0;
                                    while ((read = str.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        zip.Write(buffer, 0, buffer.Length);
                                    }
                                }

                            Nodes.ToList().ForEach(x => x.UpdateActivity(""));
                        }
                        else
                        {
                            using (FileStream str = new FileStream(session.BlendFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                int read = 0;
                                while ((read = str.Read(buffer, 0, buffer.Length)) > 0)
                                {
                                    mem.Write(buffer, 0, buffer.Length);
                                }
                            }
                        }
                        mem.Seek(0, SeekOrigin.Begin);
                        toSend = mem.ToArray();
                    });
                }
                await Task.WhenAll(Nodes.ToList().Select(async node =>
                {
                    using (MemoryStream mem = new MemoryStream(toSend))
                    {
                        SyncResponse resp = null;
                        try
                        {
                            resp = await node.SyncFile(session.SessionID, id, mem, (compress) ? Compression.GZip : Compression.Raw);
                        }
                        catch (Exception ex)
                        {
                            node.UpdateException(ex.Message);
                            return;
                        }
                        if (resp == null)
                        {
                            node.LastStatus = $"Sync Failed: No version..";
                        }
                        else
                        {
                            node.LastStatus = $"Ready";
                        }
                    }
                }).ToArray());
            }
            finally
            {
                Syncing = false;
            }
        }