Skip to content

Commit

Permalink
Use valuetask
Browse files Browse the repository at this point in the history
  • Loading branch information
adamhathcock committed Dec 3, 2024
1 parent d5f6323 commit caac2a7
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ namespace Speckle.Connectors.ArcGIS.Utils;
//don't check for GUI as it's the same check we do in ThreadContext
public class ArcGISThreadContext : ThreadContext
{
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
protected override ValueTask<T> MainToWorkerAsync<T>(Func<ValueTask<T>> action)
{
if (QueuedTask.OnWorker)
{
return action();
}
else
{
return QueuedTask.Run(action);
return QueuedTask.Run(async() => await action().BackToCurrent()).AsValueTask();
}
}

protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(action);
protected override ValueTask<T> WorkerToMainAsync<T>(Func<ValueTask<T>> action) => QueuedTask.Run(async() => await action().BackToCurrent()).AsValueTask();

protected override Task<T> MainToWorker<T>(Func<T> action)
protected override ValueTask<T> MainToWorker<T>(Func<T> action)
{
if (QueuedTask.OnWorker)
{
return Task.FromResult(action());
return new(action());
}
else
{
return QueuedTask.Run(action);
return QueuedTask.Run(action).AsValueTask();
}
}

protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
protected override ValueTask<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action).AsValueTask();
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ protected override void HostAppSaveState(string modelCardState) =>
}

map.SetMetadata(existingXmlDocument.ToString());
});
}).Wait();

protected override void LoadState() =>
_threadContext.RunOnWorker(() =>
Expand All @@ -124,5 +124,5 @@ protected override void LoadState() =>

string modelsString = element.Value;
LoadFromString(modelsString);
});
}).Wait();
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private void TryRegisterDocumentForSelection(Document? document)
// Ui requests to GetSelection() should just return this local copy that is kept up to date by the event handler.
private SelectionInfo _selectionInfo;

private async Task OnSelectionChanged()
private async ValueTask OnSelectionChanged()
{
_selectionInfo = GetSelectionInternal();
await Parent.Send(SELECTION_EVENT, _selectionInfo).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace Speckle.Connectors.Revit.Plugin;

public class RevitThreadContext : ThreadContext
{
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action) => action();
protected override ValueTask<T> MainToWorkerAsync<T>(Func<ValueTask<T>> action) => action();

protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => RevitTask.RunAsync(action);
protected override ValueTask<T> WorkerToMainAsync<T>(Func<ValueTask<T>> action) => RevitTask.RunAsync(async () => await action().BackToCurrent()).AsValueTask();

protected override Task<T> MainToWorker<T>(Func<T> action) => Task.FromResult(action());
protected override ValueTask<T> MainToWorker<T>(Func<T> action) => new(action());

protected override Task<T> WorkerToMain<T>(Func<T> action) => RevitTask.RunAsync(action);
protected override ValueTask<T> WorkerToMain<T>(Func<T> action) => new(RevitTask.RunAsync(action));
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Speckle.Connectors.Common.Extensions;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.Common.Threading;
using Speckle.Connectors.Rhino.HostApp;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
Expand All @@ -32,6 +33,7 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
private readonly RhinoGroupBaker _groupBaker;
private readonly RootObjectUnpacker _rootObjectUnpacker;
private readonly ISdkActivityFactory _activityFactory;
private readonly IThreadContext _threadContext;

public RhinoHostObjectBuilder(
IRootToHostConverter converter,
Expand All @@ -42,8 +44,7 @@ public RhinoHostObjectBuilder(
RhinoMaterialBaker materialBaker,
RhinoColorBaker colorBaker,
RhinoGroupBaker groupBaker,
ISdkActivityFactory activityFactory
)
ISdkActivityFactory activityFactory, IThreadContext threadContext)
{
_converter = converter;
_converterSettings = converterSettings;
Expand All @@ -54,6 +55,7 @@ ISdkActivityFactory activityFactory
_layerBaker = layerBaker;
_groupBaker = groupBaker;
_activityFactory = activityFactory;
_threadContext = threadContext;
}

#pragma warning disable CA1506
Expand Down Expand Up @@ -113,13 +115,13 @@ CancellationToken cancellationToken
using (var _ = _activityFactory.Start("Pre baking layers"))
{
//TODO what is this? This is going to the UI thread
RhinoApp.InvokeAndWait(() =>
_threadContext.RunOnMain(() =>
{
using var layerNoDraw = new DisableRedrawScope(_converterSettings.Current.Document.Views);
var paths = atomicObjectsWithoutInstanceComponentsWithPath.Select(t => t.path).ToList();
paths.AddRange(instanceComponentsWithPath.Select(t => t.path));
_layerBaker.CreateAllLayersForReceive(paths, baseLayerName);
});
}).Wait();
}

// 5 - Convert atomic objects
Expand Down Expand Up @@ -243,7 +245,7 @@ private void PreReceiveDeepClean(string baseLayerName)
RhinoMath.UnsetIntIndex
);

RhinoApp.InvokeAndWait(() =>
_threadContext.RunOnMain(() =>
{
_instanceBaker.PurgeInstances(baseLayerName);
_materialBaker.PurgeMaterials(baseLayerName);
Expand Down Expand Up @@ -271,7 +273,7 @@ private void PreReceiveDeepClean(string baseLayerName)

// Cleans up any previously received group
_groupBaker.PurgeGroups(baseLayerName);
});
}).Wait();
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion DUI3/Speckle.Connectors.DUI/Bridge/BrowserBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void RunMethod(string methodName, string requestId, string methodArgs) =>
}
},
_threadOptions.RunCommandsOnMainThread
);
).Wait();

/// <summary>
/// Used by the action block to invoke the actual method called by the UI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ await apiClient
return res;
}

private async Task<Base> ReceiveData(
private async ValueTask<Base> ReceiveData(
Account account,
Speckle.Sdk.Api.GraphQL.Models.Version version,
ReceiveInfo receiveInfo,
Expand Down
2 changes: 1 addition & 1 deletion Sdk/Speckle.Connectors.Common/Operations/SendOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public async Task<SendOperationResult> Execute(
return new(rootObjId, convertedReferences, buildResult.ConversionResults);
}

public async Task<SerializeProcessResults> Send(
public async ValueTask<SerializeProcessResults> Send(
Base commitObject,
SendInfo sendInfo,
IProgress<CardProgress> onOperationProgressed,
Expand Down
18 changes: 9 additions & 9 deletions Sdk/Speckle.Connectors.Common/Threading/DefaultThreadContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class DefaultThreadContext : ThreadContext
);

[SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "TaskCompletionSource")]
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action)
protected override ValueTask<T> WorkerToMainAsync<T>(Func<ValueTask<T>> action)
{
TaskCompletionSource<T> tcs = new();
_threadContext.Post(
Expand All @@ -28,17 +28,17 @@ protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action)
},
null
);
return tcs.Task;
return new ValueTask<T>(tcs.Task);
}

protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
protected override ValueTask<T> MainToWorkerAsync<T>(Func<ValueTask<T>> action)
{
Task<Task<T>> f = Task.Factory.StartNew(action, default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
return f.Unwrap();
Task<Task<T>> f = Task.Factory.StartNew(async () => await action().BackToCurrent(), default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
return new ValueTask<T>(f.Unwrap());
}

[SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "TaskCompletionSource")]
protected override Task<T> WorkerToMain<T>(Func<T> action)
protected override ValueTask<T> WorkerToMain<T>(Func<T> action)
{
TaskCompletionSource<T> tcs = new();
_threadContext.Post(
Expand All @@ -56,12 +56,12 @@ protected override Task<T> WorkerToMain<T>(Func<T> action)
},
null
);
return tcs.Task;
return new ValueTask<T>(tcs.Task);
}

protected override Task<T> MainToWorker<T>(Func<T> action)
protected override ValueTask<T> MainToWorker<T>(Func<T> action)
{
Task<T> f = Task.Factory.StartNew(action, default, TaskCreationOptions.LongRunning, TaskScheduler.Default);
return f;
return new ValueTask<T>(f);
}
}
33 changes: 16 additions & 17 deletions Sdk/Speckle.Connectors.Common/Threading/ThreadContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace Speckle.Connectors.Common.Threading;
[GenerateAutoInterface]
public abstract class ThreadContext : IThreadContext
{
private static readonly Task<object?> s_completedTask = Task.FromResult<object?>(null);


public static bool IsMainThread => Environment.CurrentManagedThreadId == 1 && !Thread.CurrentThread.IsBackground;

public async Task RunOnThread(Action action, bool useMain)
public async ValueTask RunOnThread(Action action, bool useMain)
{
if (useMain)
{
Expand All @@ -22,7 +22,7 @@ public async Task RunOnThread(Action action, bool useMain)
await WorkerToMainAsync(() =>
{
action();
return s_completedTask;
return new ValueTask<object?>();
})
.ConfigureAwait(false);
}
Expand All @@ -34,7 +34,7 @@ await WorkerToMainAsync(() =>
await MainToWorkerAsync(() =>
{
action();
return s_completedTask;
return new ValueTask<object?>();
})
.BackToAny();
}
Expand All @@ -45,13 +45,13 @@ await MainToWorkerAsync(() =>
}
}

public virtual Task<T> RunOnThread<T>(Func<T> action, bool useMain)
public virtual ValueTask<T> RunOnThread<T>(Func<T> action, bool useMain)
{
if (useMain)
{
if (IsMainThread)
{
return Task.FromResult(action());
return new ValueTask<T>(action());
}

return WorkerToMain(action);
Expand All @@ -61,10 +61,10 @@ public virtual Task<T> RunOnThread<T>(Func<T> action, bool useMain)
return MainToWorker(action);
}

return Task.FromResult(action());
return new ValueTask<T>(action());
}

public async Task RunOnThreadAsync(Func<Task> action, bool useMain)
public async ValueTask RunOnThreadAsync(Func<ValueTask> action, bool useMain)
{
if (useMain)
{
Expand All @@ -77,7 +77,7 @@ public async Task RunOnThreadAsync(Func<Task> action, bool useMain)
await WorkerToMainAsync<object?>(async () =>
{
await action().BackToCurrent();
return null;
return new ValueTask<object?>(null);
})
.BackToCurrent();
}
Expand All @@ -88,8 +88,8 @@ public async Task RunOnThreadAsync(Func<Task> action, bool useMain)
{
await MainToWorkerAsync<object?>(async () =>
{
await action().BackToCurrent();
return null;
await action().BackToCurrent();
return new ValueTask<object?>(null);
})
.BackToCurrent();
}
Expand All @@ -100,7 +100,7 @@ public async Task RunOnThreadAsync(Func<Task> action, bool useMain)
}
}

public Task<T> RunOnThreadAsync<T>(Func<Task<T>> action, bool useMain)
public ValueTask<T> RunOnThreadAsync<T>(Func<ValueTask<T>> action, bool useMain)
{
if (useMain)
{
Expand All @@ -117,11 +117,10 @@ public Task<T> RunOnThreadAsync<T>(Func<Task<T>> action, bool useMain)
}
return action();
}
protected abstract ValueTask<T> WorkerToMainAsync<T>(Func<ValueTask<T>> action);

protected abstract Task<T> WorkerToMainAsync<T>(Func<Task<T>> action);

protected abstract Task<T> MainToWorkerAsync<T>(Func<Task<T>> action);
protected abstract Task<T> WorkerToMain<T>(Func<T> action);
protected abstract ValueTask<T> MainToWorkerAsync<T>(Func<ValueTask<T>> action);
protected abstract ValueTask<T> WorkerToMain<T>(Func<T> action);

protected abstract Task<T> MainToWorker<T>(Func<T> action);
protected abstract ValueTask<T> MainToWorker<T>(Func<T> action);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@

public static class ThreadContextExtensions
{
public static void RunOnMain(this IThreadContext threadContext, Action action) =>
public static ValueTask RunOnMain(this IThreadContext threadContext, Action action) =>
threadContext.RunOnThread(action, true);

public static void RunOnWorker(this IThreadContext threadContext, Action action) =>
public static ValueTask RunOnWorker(this IThreadContext threadContext, Action action) =>
threadContext.RunOnThread(action, false);

public static Task<T> RunOnMain<T>(this IThreadContext threadContext, Func<T> action) =>
public static ValueTask<T> RunOnMain<T>(this IThreadContext threadContext, Func<T> action) =>
threadContext.RunOnThread(action, true);

public static Task<T> RunOnWorker<T>(this IThreadContext threadContext, Func<T> action) =>
public static ValueTask<T> RunOnWorker<T>(this IThreadContext threadContext, Func<T> action) =>
threadContext.RunOnThread(action, false);

public static Task RunOnMainAsync(this IThreadContext threadContext, Func<Task> action) =>
public static ValueTask RunOnMainAsync(this IThreadContext threadContext, Func<ValueTask> action) =>
threadContext.RunOnThreadAsync(action, true);

public static Task RunOnWorkerAsync(this IThreadContext threadContext, Func<Task> action) =>
public static ValueTask RunOnWorkerAsync(this IThreadContext threadContext, Func<ValueTask> action) =>
threadContext.RunOnThreadAsync(action, false);

public static Task<T> RunOnMainAsync<T>(this IThreadContext threadContext, Func<Task<T>> action) =>
public static ValueTask<T> RunOnMainAsync<T>(this IThreadContext threadContext, Func<ValueTask<T>> action) =>
threadContext.RunOnThreadAsync(action, true);

public static Task<T> RunOnWorkerAsync<T>(this IThreadContext threadContext, Func<Task<T>> action) =>
public static ValueTask<T> RunOnWorkerAsync<T>(this IThreadContext threadContext, Func<ValueTask<T>> action) =>
threadContext.RunOnThreadAsync(action, false);
}
12 changes: 11 additions & 1 deletion Sdk/Speckle.Connectors.Common/Threading/Yield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Speckle.Connectors.Common.Threading;

public static class Yield
public static class TaskExtensions
{
public static ConfiguredValueTaskAwaitable<T> BackToCurrent<T> (this ValueTask<T> valueTask) => valueTask.ConfigureAwait(true);

public static ConfiguredValueTaskAwaitable<T> BackToAny<T>(this ValueTask<T> valueTask) => valueTask.ConfigureAwait(false);
public static ConfiguredValueTaskAwaitable BackToCurrent(this ValueTask valueTask) => valueTask.ConfigureAwait(true);

public static ConfiguredValueTaskAwaitable BackToAny(this ValueTask valueTask) => valueTask.ConfigureAwait(false);
Expand All @@ -15,4 +18,11 @@ public static class Yield
public static ConfiguredTaskAwaitable<T> BackToCurrent<T>(this Task<T> task) => task.ConfigureAwait(true);

public static ConfiguredTaskAwaitable<T> BackToAny<T>(this Task<T> task) => task.ConfigureAwait(false);

public static ValueTask AsValueTask(this Task task) => new(task);
public static ValueTask<T> AsValueTask<T>(this Task<T> task) => new(task);
public static void Wait(this Task task) => task.GetAwaiter().GetResult();
public static T Wait<T>(this Task<T> task) => task.GetAwaiter().GetResult();
public static void Wait(this ValueTask task) => task.GetAwaiter().GetResult();
public static T Wait<T>(this ValueTask<T> task) => task.GetAwaiter().GetResult();
}

0 comments on commit caac2a7

Please sign in to comment.