mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-17 12:40:11 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
887db5b281 | ||
|
|
fee5518a82 | ||
|
|
551128e64c | ||
|
|
c65ae8d18e | ||
|
|
c1f75d9ebd | ||
|
|
73a5ff6648 |
34
README.md
34
README.md
@@ -532,6 +532,38 @@ SelectAwaitWithCancellation(Func<T, CancellationToken, UniTask<TR>> selector)
|
|||||||
|
|
||||||
If you want to use the `async` method inside the func, use the `***Await` or `***AwaitWithCancellation`.
|
If you want to use the `async` method inside the func, use the `***Await` or `***AwaitWithCancellation`.
|
||||||
|
|
||||||
|
How to create async iterator, C# 8.0 supports async iterator(`async yield return`) but it only allows `IAsyncEnumerable<T>` and of course requires C# 8.0. UniTask supports `UniTaskAsyncEnumerable.Create` method to create custom async iterator.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// IAsyncEnumerable, C# 8.0 version of async iterator. ( do not use this style, IAsyncEnumerable is not controled in UniTask).
|
||||||
|
public async IAsyncEnumerable<int> MyEveryUpdate([EnumeratorCancellation]CancellationToken cancelationToken)
|
||||||
|
{
|
||||||
|
var frameCount = 0;
|
||||||
|
await UniTask.Yield();
|
||||||
|
while (!token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
yield return frameCount++;
|
||||||
|
await UniTask.Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UniTaskAsyncEnumerable.Create and use `await writer.YieldAsync` instead of `yield return`.
|
||||||
|
public IUniTaskAsyncEnumerable<int> MyEveryUpdate()
|
||||||
|
{
|
||||||
|
// writer(IAsyncWriter<T>) has `YieldAsync(value)` method.
|
||||||
|
return UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
var frameCount = 0;
|
||||||
|
await UniTask.Yield();
|
||||||
|
while (!token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await writer.YieldAsync(frameCount++); // instead of `yield return`
|
||||||
|
await UniTask.Yield();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Awaitable Events
|
Awaitable Events
|
||||||
---
|
---
|
||||||
All uGUI component implements `***AsAsyncEnumerable` to convert asynchronous streams of events.
|
All uGUI component implements `***AsAsyncEnumerable` to convert asynchronous streams of events.
|
||||||
@@ -812,7 +844,7 @@ After Unity 2019.3.4f1, Unity 2020.1a21, that support path query parameter of gi
|
|||||||
|
|
||||||
or add `"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"` to `Packages/manifest.json`.
|
or add `"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"` to `Packages/manifest.json`.
|
||||||
|
|
||||||
If you want to set a target version, UniTask is using `*.*.*` release tag so you can specify a version like `#2.0.22`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.0.22`.
|
If you want to set a target version, UniTask is using `*.*.*` release tag so you can specify a version like `#2.0.24`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.0.24`.
|
||||||
|
|
||||||
### Install via OpenUPM
|
### Install via OpenUPM
|
||||||
|
|
||||||
|
|||||||
@@ -295,71 +295,25 @@ namespace NetCoreSandbox
|
|||||||
//await new ComparisonBenchmarks().ViaUniTaskT();
|
//await new ComparisonBenchmarks().ViaUniTaskT();
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
// await new AllocationCheck().ViaUniTaskVoid();
|
|
||||||
|
|
||||||
var buttonTest = new AsyncReactiveProperty<AsyncUnit>(AsyncUnit.Default);
|
var e = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
|
||||||
buttonTest
|
|
||||||
.Subscribe(async _ =>
|
|
||||||
{
|
{
|
||||||
try
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
await new Foo().MethodFooAsync();
|
Console.WriteLine($"Start {i}");
|
||||||
}
|
await writer.YieldAsync(i);
|
||||||
catch (Exception e)
|
Console.WriteLine($"End {i}");
|
||||||
{
|
|
||||||
Console.WriteLine(e.StackTrace);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonTest.Value = AsyncUnit.Default;
|
var ee = e.GetAsyncEnumerator();
|
||||||
|
while (await ee.MoveNextAsync())
|
||||||
|
|
||||||
// AsyncTest().Forge
|
|
||||||
|
|
||||||
Console.WriteLine("A?");
|
|
||||||
var a = await new ZeroAllocAsyncAwaitInDotNetCore().NanikaAsync(1, 2);
|
|
||||||
Console.WriteLine("RET:" + a);
|
|
||||||
await WhereSelect();
|
|
||||||
|
|
||||||
SynchronizationContext.SetSynchronizationContext(new MySyncContext());
|
|
||||||
|
|
||||||
await Aaa();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//AsyncTest().Forget();
|
|
||||||
|
|
||||||
// AsyncTest().Forget();
|
|
||||||
|
|
||||||
ThreadPool.SetMinThreads(100, 100);
|
|
||||||
|
|
||||||
//List<UniTask<int>> list = new List<UniTask<int>>();
|
|
||||||
for (int i = 0; i < short.MaxValue; i++)
|
|
||||||
{
|
{
|
||||||
//// list.Add(AsyncTest());
|
Console.WriteLine("ForEach " + ee.Current);
|
||||||
await YieldCore();
|
|
||||||
}
|
}
|
||||||
//await UniTask.WhenAll(list);
|
|
||||||
|
|
||||||
//Console.WriteLine("TOGO");
|
|
||||||
|
|
||||||
//var a = await AsyncTest();
|
|
||||||
//var b = AsyncTest();
|
|
||||||
//var c = AsyncTest();
|
|
||||||
await YieldCore();
|
|
||||||
|
|
||||||
//await b;
|
|
||||||
//await c;
|
|
||||||
|
|
||||||
|
|
||||||
//foreach (var item in Cysharp.Threading.Tasks.Internal.TaskPool.GetCacheSizeInfo())
|
|
||||||
//{
|
|
||||||
// Console.WriteLine(item);
|
|
||||||
//}
|
|
||||||
|
|
||||||
Console.ReadLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async UniTask YieldCore()
|
static async UniTask YieldCore()
|
||||||
|
|||||||
170
src/UniTask.NetCoreTests/Linq/CreateTest.cs
Normal file
170
src/UniTask.NetCoreTests/Linq/CreateTest.cs
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#pragma warning disable CS1998
|
||||||
|
#pragma warning disable CS0162
|
||||||
|
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using Cysharp.Threading.Tasks.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace NetCoreTests.Linq
|
||||||
|
{
|
||||||
|
public class CreateTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task SyncCreation()
|
||||||
|
{
|
||||||
|
var from = 10;
|
||||||
|
var count = 100;
|
||||||
|
|
||||||
|
var xs = await UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
await writer.YieldAsync(from + i);
|
||||||
|
}
|
||||||
|
}).ToArrayAsync();
|
||||||
|
|
||||||
|
var ys = await Range(from, count).AsUniTaskAsyncEnumerable().ToArrayAsync();
|
||||||
|
|
||||||
|
xs.Should().BeEquivalentTo(ys);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SyncManually()
|
||||||
|
{
|
||||||
|
var list = new List<int>();
|
||||||
|
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
list.Add(100);
|
||||||
|
await writer.YieldAsync(10);
|
||||||
|
|
||||||
|
list.Add(200);
|
||||||
|
await writer.YieldAsync(20);
|
||||||
|
|
||||||
|
list.Add(300);
|
||||||
|
await writer.YieldAsync(30);
|
||||||
|
|
||||||
|
list.Add(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
list.Should().BeEmpty();
|
||||||
|
var e = xs.GetAsyncEnumerator();
|
||||||
|
|
||||||
|
list.Should().BeEmpty();
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100);
|
||||||
|
e.Current.Should().Be(10);
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100, 200);
|
||||||
|
e.Current.Should().Be(20);
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100, 200, 300);
|
||||||
|
e.Current.Should().Be(30);
|
||||||
|
|
||||||
|
(await e.MoveNextAsync()).Should().BeFalse();
|
||||||
|
list.Should().BeEquivalentTo(100, 200, 300, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SyncExceptionFirst()
|
||||||
|
{
|
||||||
|
var from = 10;
|
||||||
|
var count = 100;
|
||||||
|
|
||||||
|
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
throw new UniTaskTestException();
|
||||||
|
await writer.YieldAsync(from + i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task SyncException()
|
||||||
|
{
|
||||||
|
var from = 10;
|
||||||
|
var count = 100;
|
||||||
|
|
||||||
|
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
await writer.YieldAsync(from + i);
|
||||||
|
|
||||||
|
if (i == 15)
|
||||||
|
{
|
||||||
|
throw new UniTaskTestException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ASyncManually()
|
||||||
|
{
|
||||||
|
var list = new List<int>();
|
||||||
|
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
await UniTask.Yield();
|
||||||
|
|
||||||
|
list.Add(100);
|
||||||
|
await writer.YieldAsync(10);
|
||||||
|
|
||||||
|
await UniTask.Yield();
|
||||||
|
|
||||||
|
list.Add(200);
|
||||||
|
await writer.YieldAsync(20);
|
||||||
|
|
||||||
|
await UniTask.Yield();
|
||||||
|
list.Add(300);
|
||||||
|
await UniTask.Yield();
|
||||||
|
await writer.YieldAsync(30);
|
||||||
|
|
||||||
|
await UniTask.Yield();
|
||||||
|
|
||||||
|
list.Add(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
list.Should().BeEmpty();
|
||||||
|
var e = xs.GetAsyncEnumerator();
|
||||||
|
|
||||||
|
list.Should().BeEmpty();
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100);
|
||||||
|
e.Current.Should().Be(10);
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100, 200);
|
||||||
|
e.Current.Should().Be(20);
|
||||||
|
|
||||||
|
await e.MoveNextAsync();
|
||||||
|
list.Should().BeEquivalentTo(100, 200, 300);
|
||||||
|
e.Current.Should().Be(30);
|
||||||
|
|
||||||
|
(await e.MoveNextAsync()).Should().BeFalse();
|
||||||
|
list.Should().BeEquivalentTo(100, 200, 300, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
async IAsyncEnumerable<int> Range(int from, int count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
yield return from + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
192
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/Create.cs
Normal file
192
src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/Create.cs
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
using Cysharp.Threading.Tasks.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Cysharp.Threading.Tasks.Linq
|
||||||
|
{
|
||||||
|
public static partial class UniTaskAsyncEnumerable
|
||||||
|
{
|
||||||
|
public static IUniTaskAsyncEnumerable<T> Create<T>(Func<IAsyncWriter<T>, CancellationToken, UniTask> create)
|
||||||
|
{
|
||||||
|
Error.ThrowArgumentNullException(create, nameof(create));
|
||||||
|
return new Create<T>(create);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IAsyncWriter<T>
|
||||||
|
{
|
||||||
|
UniTask YieldAsync(T value);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Create<T> : IUniTaskAsyncEnumerable<T>
|
||||||
|
{
|
||||||
|
readonly Func<IAsyncWriter<T>, CancellationToken, UniTask> create;
|
||||||
|
|
||||||
|
public Create(Func<IAsyncWriter<T>, CancellationToken, UniTask> create)
|
||||||
|
{
|
||||||
|
this.create = create;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return new _Create(create, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class _Create : MoveNextSource, IUniTaskAsyncEnumerator<T>
|
||||||
|
{
|
||||||
|
readonly Func<IAsyncWriter<T>, CancellationToken, UniTask> create;
|
||||||
|
readonly CancellationToken cancellationToken;
|
||||||
|
|
||||||
|
int state = -1;
|
||||||
|
AsyncWriter writer;
|
||||||
|
|
||||||
|
public _Create(Func<IAsyncWriter<T>, CancellationToken, UniTask> create, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
this.create = create;
|
||||||
|
this.cancellationToken = cancellationToken;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Current { get; private set; }
|
||||||
|
|
||||||
|
public UniTask DisposeAsync()
|
||||||
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTask<bool> MoveNextAsync()
|
||||||
|
{
|
||||||
|
if (state == -2) return default;
|
||||||
|
|
||||||
|
completionSource.Reset();
|
||||||
|
MoveNext();
|
||||||
|
return new UniTask<bool>(this, completionSource.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveNext()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case -1: // init
|
||||||
|
{
|
||||||
|
writer = new AsyncWriter(this);
|
||||||
|
RunWriterTask(create(writer, cancellationToken)).Forget();
|
||||||
|
if (Volatile.Read(ref state) == -2)
|
||||||
|
{
|
||||||
|
return; // complete synchronously
|
||||||
|
}
|
||||||
|
state = 0; // wait YieldAsync, it set TrySetResult(true)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 0:
|
||||||
|
writer.SignalWriter();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
state = -2;
|
||||||
|
completionSource.TrySetException(ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
state = -2;
|
||||||
|
completionSource.TrySetResult(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async UniTaskVoid RunWriterTask(UniTask task)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await task;
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Volatile.Write(ref state, -2);
|
||||||
|
completionSource.TrySetException(ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
Volatile.Write(ref state, -2);
|
||||||
|
completionSource.TrySetResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TrySetCanceled(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
state = -2;
|
||||||
|
return completionSource.TrySetCanceled(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TrySetComplete()
|
||||||
|
{
|
||||||
|
state = -2;
|
||||||
|
return completionSource.TrySetResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TrySetException(Exception error)
|
||||||
|
{
|
||||||
|
state = -2;
|
||||||
|
return completionSource.TrySetException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetResult(T value)
|
||||||
|
{
|
||||||
|
Current = value;
|
||||||
|
completionSource.TrySetResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class AsyncWriter : IUniTaskSource, IAsyncWriter<T>
|
||||||
|
{
|
||||||
|
readonly _Create enumerator;
|
||||||
|
|
||||||
|
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||||
|
|
||||||
|
public AsyncWriter(_Create enumerator)
|
||||||
|
{
|
||||||
|
this.enumerator = enumerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetResult(short token)
|
||||||
|
{
|
||||||
|
core.GetResult(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus GetStatus(short token)
|
||||||
|
{
|
||||||
|
return core.GetStatus(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus UnsafeGetStatus()
|
||||||
|
{
|
||||||
|
return core.UnsafeGetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTask YieldAsync(T value)
|
||||||
|
{
|
||||||
|
core.Reset();
|
||||||
|
enumerator.SetResult(value);
|
||||||
|
return new UniTask(this, core.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignalWriter()
|
||||||
|
{
|
||||||
|
core.TrySetResult(AsyncUnit.Default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0202f723469f93945afa063bfb440d15
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -88,6 +88,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -156,6 +157,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,6 +197,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -263,6 +266,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,6 +306,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -382,6 +387,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,6 +428,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -502,6 +509,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,6 +549,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -621,6 +630,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -661,6 +671,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TResult Current { get; private set; }
|
public TResult Current { get; private set; }
|
||||||
@@ -741,6 +752,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -165,6 +166,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,6 +206,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -281,6 +284,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,6 +324,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -410,6 +415,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -450,6 +456,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -540,6 +547,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,6 +587,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -669,6 +678,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,6 +719,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.cancellationToken = cancellationToken;
|
this.cancellationToken = cancellationToken;
|
||||||
this.moveNextAction = MoveNext;
|
this.moveNextAction = MoveNext;
|
||||||
|
TaskTracker.TrackActiveTask(this, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSource Current { get; private set; }
|
public TSource Current { get; private set; }
|
||||||
@@ -799,6 +810,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
|||||||
|
|
||||||
public UniTask DisposeAsync()
|
public UniTask DisposeAsync()
|
||||||
{
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
return enumerator.DisposeAsync();
|
return enumerator.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,6 +175,22 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return new UniTask<T>(new DeferPromise<T>(factory), 0);
|
return new UniTask<T>(new DeferPromise<T>(factory), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Never complete.
|
||||||
|
/// </summary>
|
||||||
|
public static UniTask Never(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return new UniTask<AsyncUnit>(new NeverPromise<AsyncUnit>(cancellationToken), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Never complete.
|
||||||
|
/// </summary>
|
||||||
|
public static UniTask<T> Never<T>(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return new UniTask<T>(new NeverPromise<T>(cancellationToken), 0);
|
||||||
|
}
|
||||||
|
|
||||||
sealed class ExceptionResultSource : IUniTaskSource
|
sealed class ExceptionResultSource : IUniTaskSource
|
||||||
{
|
{
|
||||||
readonly ExceptionDispatchInfo exception;
|
readonly ExceptionDispatchInfo exception;
|
||||||
@@ -384,6 +400,54 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return task.Status;
|
return task.Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class NeverPromise<T> : IUniTaskSource<T>
|
||||||
|
{
|
||||||
|
static readonly Action<object> cancellationCallback = CancellationCallback;
|
||||||
|
|
||||||
|
CancellationToken cancellationToken;
|
||||||
|
UniTaskCompletionSourceCore<T> core;
|
||||||
|
|
||||||
|
public NeverPromise(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
this.cancellationToken = cancellationToken;
|
||||||
|
if (this.cancellationToken.CanBeCanceled)
|
||||||
|
{
|
||||||
|
this.cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CancellationCallback(object state)
|
||||||
|
{
|
||||||
|
var self = (NeverPromise<T>)state;
|
||||||
|
self.core.TrySetCanceled(self.cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetResult(short token)
|
||||||
|
{
|
||||||
|
return core.GetResult(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus GetStatus(short token)
|
||||||
|
{
|
||||||
|
return core.GetStatus(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus UnsafeGetStatus()
|
||||||
|
{
|
||||||
|
return core.UnsafeGetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IUniTaskSource.GetResult(short token)
|
||||||
|
{
|
||||||
|
core.GetResult(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class CompletedTasks
|
internal static class CompletedTasks
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
ValidateToken(token);
|
ValidateToken(token);
|
||||||
if (completedCount == 0)
|
if (completedCount == 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("not yet completed.");
|
throw new InvalidOperationException("Not yet completed, UniTask only allow to use await.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != null)
|
if (error != null)
|
||||||
@@ -288,7 +288,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
// It will cause call OnCompleted multiple time, invalid.
|
// It will cause call OnCompleted multiple time, invalid.
|
||||||
if (!ReferenceEquals(oldContinuation, UniTaskCompletionSourceCoreShared.s_sentinel))
|
if (!ReferenceEquals(oldContinuation, UniTaskCompletionSourceCoreShared.s_sentinel))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException("Already continuation registered, can not await twice or get Status after await.");
|
||||||
}
|
}
|
||||||
|
|
||||||
continuation(state);
|
continuation(state);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.cysharp.unitask",
|
"name": "com.cysharp.unitask",
|
||||||
"displayName": "UniTask",
|
"displayName": "UniTask",
|
||||||
"version": "2.0.23",
|
"version": "2.0.24",
|
||||||
"unity": "2018.4",
|
"unity": "2018.4",
|
||||||
"description": "Provides an efficient async/await integration to Unity.",
|
"description": "Provides an efficient async/await integration to Unity.",
|
||||||
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
||||||
|
|||||||
@@ -1,46 +1,52 @@
|
|||||||
using System;
|
using Cysharp.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
using System;
|
||||||
using Cysharp.Threading.Tasks;
|
using System.Collections.Generic;
|
||||||
using Cysharp.Threading.Tasks.Linq;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
|
/*UNniTastWhenAnyTester*/
|
||||||
|
|
||||||
|
[ExecuteInEditMode]
|
||||||
public class ExceptionExamples : MonoBehaviour
|
public class ExceptionExamples : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Button ButtonTest;
|
public bool apply = false;
|
||||||
|
|
||||||
void Start()
|
private async UniTaskVoid Update()
|
||||||
{
|
{
|
||||||
ButtonTest.OnClickAsAsyncEnumerable()
|
if (apply)
|
||||||
.Subscribe(async _ =>
|
{
|
||||||
|
apply = false;
|
||||||
|
await LaunchTasksAndDetectWhenAnyDone(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async UniTask LaunchTasksAndDetectWhenAnyDone(int nbTasks)
|
||||||
|
{
|
||||||
|
List<UniTask<int>> sleeptasks = new List<UniTask<int>>();
|
||||||
|
for (int i = 0; i < nbTasks; i++)
|
||||||
|
{
|
||||||
|
sleeptasks.Add(SleepAndReturnTrue(i).ToAsyncLazy().Task);
|
||||||
|
}
|
||||||
|
while (sleeptasks.Count > 0)
|
||||||
|
{
|
||||||
|
Debug.Log(DateTime.Now.ToString() + " waiting for " + sleeptasks.Count + " tasks...");
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
(int index, int taskID) = await UniTask.WhenAny(sleeptasks);
|
||||||
{
|
Debug.Log(DateTime.Now.ToString() + " Sleep task " + taskID + " done");
|
||||||
await new Foo().MethodFooAsync();
|
sleeptasks.RemoveAt(index);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch
|
||||||
{
|
{
|
||||||
Debug.Log(e.StackTrace);
|
throw;
|
||||||
}
|
//Debug.Log("Error: " + e.Message);
|
||||||
}, this.GetCancellationTokenOnDestroy());
|
//return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
class Foo
|
|
||||||
{
|
private async UniTask<int> SleepAndReturnTrue(int taskIndex)
|
||||||
public async UniTask MethodFooAsync()
|
{
|
||||||
{
|
await UniTask.Delay(100);
|
||||||
await MethodBarAsync();
|
return taskIndex;
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask MethodBarAsync()
|
|
||||||
{
|
|
||||||
Throw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Throw()
|
|
||||||
{
|
|
||||||
throw new Exception();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,18 +459,41 @@ public class SandboxMain : MonoBehaviour
|
|||||||
PrepareCamera();
|
PrepareCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IUniTaskAsyncEnumerable<int> MyEveryUpdate()
|
||||||
|
{
|
||||||
|
return UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
|
||||||
|
{
|
||||||
|
var frameCount = 0;
|
||||||
|
await UniTask.Yield();
|
||||||
|
while (!token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
await writer.YieldAsync(frameCount++); // instead of `yield return`
|
||||||
|
await UniTask.Yield();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async UniTaskVoid Start()
|
async UniTaskVoid Start()
|
||||||
{
|
{
|
||||||
|
var cts = new CancellationTokenSource();
|
||||||
okButton.onClick.AddListener(() =>
|
okButton.onClick.AddListener(() =>
|
||||||
{
|
{
|
||||||
ShootAsync().Forget();
|
cts.Cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Nanika();
|
//// Nanika();
|
||||||
|
|
||||||
|
|
||||||
|
//await UniTask.Yield();
|
||||||
|
|
||||||
|
|
||||||
|
await MyEveryUpdate().Select(x => x).Where(x => x % 2 == 0).ForEachAsync(x =>
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log(x + ":" + Time.frameCount);
|
||||||
|
}, cts.Token);
|
||||||
|
|
||||||
|
|
||||||
await UniTask.Yield();
|
|
||||||
// this.GetCancellationTokenOnDestroy()
|
// this.GetCancellationTokenOnDestroy()
|
||||||
|
|
||||||
//PlayerLoopInfo.Inject();
|
//PlayerLoopInfo.Inject();
|
||||||
@@ -992,17 +1015,17 @@ public class SandboxMain : MonoBehaviour
|
|||||||
|
|
||||||
void PrepareCamera()
|
void PrepareCamera()
|
||||||
{
|
{
|
||||||
Debug.Log("Support AsyncGPUReadback:" + SystemInfo.supportsAsyncGPUReadback);
|
//Debug.Log("Support AsyncGPUReadback:" + SystemInfo.supportsAsyncGPUReadback);
|
||||||
|
|
||||||
var width = 480;
|
//var width = 480;
|
||||||
var height = 240;
|
//var height = 240;
|
||||||
var depth = 24;
|
//var depth = 24;
|
||||||
|
|
||||||
mycamera.targetTexture = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
|
//mycamera.targetTexture = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
|
||||||
{
|
//{
|
||||||
antiAliasing = 8
|
// antiAliasing = 8
|
||||||
};
|
//};
|
||||||
mycamera.enabled = true;
|
//mycamera.enabled = true;
|
||||||
|
|
||||||
//myRenderTexture = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
|
//myRenderTexture = new RenderTexture(width, height, depth, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default)
|
||||||
//{
|
//{
|
||||||
|
|||||||
Reference in New Issue
Block a user