public async Task <ServerActionResult> SendToServer() { var t = Log.MethodEntered(); await TaskV2.Delay(10); // communication with server would happen here sentToServerCounter++; if (simulateOneTimeout) { simulateOneTimeout = false; return(ServerActionResult.RETRY); } if (simulateError) { return(ServerActionResult.FAIL); } // After communicating with the server an additional store update might be needed: var serverConfirmedEmail = true; // <- this answer would come from the server var store = IoC.inject.Get <DataStore <MyAppState1> >(this); store.Dispatch(new ActionOnUser.EmailConfirmed() { targetEmail = newEmail, isEmailConfirmed = serverConfirmedEmail }); return(ServerActionResult.SUCCESS); }
private async Task <string> SomeAsyncFailingTask2() { var t = Log.MethodEntered(); await TaskV2.Delay(5); throw new Exception("task failed as requested"); }
private async Task HandleLongPress() { // Only execute long press detection if there are listeners registered: if (onLongPressStart.IsNullOrEmpty() && onLongPressEnd.IsNullOrEmpty()) { return; } var isPointerUpAgain = pointerUpTask.Task; await TaskV2.Delay(longPressDurInMs); var distanceInPixels = latestPointer.position - pointerDown.position; if (distanceInPixels.magnitude > maxPixelDistance) { return; } if (!isPointerUpAgain.IsCompleted) { SetClickResult(ClickResult.longPress); onLongPressStart?.Invoke(); await pointerUpTask.Task; onLongPressEnd?.Invoke(); } }
private static async Task TestErrorDetectionWithMultipleThreads(Func <Task> newErrorTask) { var d = new MyDisposable(); using (d) { Task t1 = TaskV2.Run(newErrorTask); Task t2 = null, t3 = null; try { Assert.False(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); t2 = TaskV2.Run(newErrorTask); Assert.False(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); t3 = TaskV2.Run(newErrorTask); Assert.False(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); await Task.WhenAll(t1, t2, t3); } catch (Exception) { Assert.True(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); } Assert.False(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); Assert.True(t1.IsCompleted); Assert.True(t2.IsCompleted); Assert.True(t3.IsCompleted); Assert.True(t1.IsFaulted); Assert.True(t2.IsFaulted); Assert.True(t3.IsFaulted); } Assert.False(d.DEBUG_ThrownExceptionDetectedInCurrentContext()); Assert.False(d.exceptionWasDetected); }
private async Task DelayAndThenForceProcessBatch() { Log.MethodEntered(); await TaskV2.Delay(2000); await BatchProcess(); }
public IEnumerator TestMixingBackgroundAndMainThread() { var timing = Log.MethodEntered("TestMixingBackgroundAndMainThread"); var backgroundTask1IsDone = false; yield return(TaskRunner.instance.RunInBackground(async(c) => { Assert.IsFalse(MainThread.isMainThread); await TaskV2.Delay(100); backgroundTask1IsDone = true; }).AsCoroutine()); Assert.IsTrue(backgroundTask1IsDone); Assert.IsTrue(MainThread.isMainThread); var backgroundTask2 = TaskRunner.instance.RunInBackground(async(c) => { Assert.IsFalse(MainThread.isMainThread); await TaskV2.Delay(100); c.ThrowIfCancellationRequested(); return("some result"); }); yield return(backgroundTask2.AsCoroutine()); Assert.IsTrue(backgroundTask2.task.IsCompleted); Assert.AreEqual("some result", backgroundTask2.task.Result); Assert.IsTrue(timing.ElapsedMilliseconds > 200, "t=" + timing.ElapsedMilliseconds); Log.MethodDone(timing); }
public async Task TestThrottledDebounce2() { int counter = 0; EventHandler <int> action = (_, myIntParam) => { Log.d("myIntParam=" + myIntParam); Interlocked.Increment(ref counter); }; var throttledAction = action.AsThrottledDebounce(delayInMs: 5); var tasks = new List <Task>(); for (int i = 0; i < 100; i++) // Do 100 calls of the method in parallel: { var myIntParam = i; tasks.Add(TaskV2.Run(() => { throttledAction(this, myIntParam); })); } await Task.WhenAll(tasks.ToArray()); for (int i = 0; i < 20; i++) { await TaskV2.Delay(30); if (counter >= 2) { break; } } Assert.Equal(2, counter); await TaskV2.Delay(100); Assert.Equal(2, counter); }
public IEnumerator TestTaskCancel1() { var timing = Log.MethodEntered("TestTaskCancel"); BackgroundTaskQueue queue = BackgroundTaskQueue.NewBackgroundTaskQueue(1); var counter = 0; var task1 = queue.Run(async(c) => { Assert.IsFalse(MainThread.isMainThread); for (int i = 0; i < int.MaxValue; i++) { await TaskV2.Delay(10); counter++; c.ThrowIfCancellationRequested(); } }); yield return(new WaitForSeconds(0.2f)); queue.CancelAllOpenTasks(); yield return(task1.AsCoroutine(onError: e => { Assert.True(e is AggregateException a1 && a1.InnerException is AggregateException a2 && a2.InnerException is TaskCanceledException); })); Assert.IsFalse(task1.IsCanceled); // It was already running so it faulted instead of being canceled Assert.IsTrue(task1.IsFaulted); Assert.IsTrue(counter > 10, "counter=" + counter); Assert.IsTrue(counter < 50, "counter=" + counter); Log.MethodDone(timing); }
public void TestTemporaryContext1() { var IoC_inject = GetInjectorForTest(); Assert.Null(IoC_inject.Get <MyClass1>(this)); for (int i = 0; i < 100; i++) { TaskV2.Run(() => { var myContextInstance1 = new MyClass1(); IoC_inject.DoWithTempContext <MyClass1>(myContextInstance1, () => { Assert.Equal(myContextInstance1, IoC_inject.Get <MyClass1>(this)); }); // when the temporary context is gone requesting an injection returns null again: Assert.Null(IoC_inject.Get <MyClass1>(this)); var myContextInstance2 = new MyClass1(); var testUser = new MyUserClass1(); IoC_inject.DoWithTempContext <MyClass1>(myContextInstance2, () => { IoC_inject.DoWithTempContext <MyUserClass1>(testUser, () => { Assert.Equal(myContextInstance2, IoC_inject.Get <MyClass1>(this)); Assert.Equal(testUser, IoC_inject.Get <MyUserClass1>(this)); }); }); // when the temporary context is gone requesting an injection returns null again: Assert.Null(IoC_inject.Get <MyClass1>(this)); Assert.Null(IoC_inject.Get <MyUserClass1>(this)); }); } }
public async Task ThrottledDebounceExample1() { int counter = 0; Action action = () => { Interlocked.Increment(ref counter); }; // Make the action throttled / debounced: action = action.AsThrottledDebounce(delayInMs: 50); // Call it multiple times with less then 50ms between the calls: action(); // The first call will always be passed through action(); // This one will be delayed and never called because its canceled by the next call: action(); // This one will be delayed and never called because its canceled by the next call: action(); // This will be delayed for 50ms and then triggered because no additional call follows after it // Wait a little bit until the action was triggered at least 2 times: for (int i = 0; i < 100; i++) { await TaskV2.Delay(200); if (counter >= 2) { break; } } Assert.Equal(2, counter); }
public async Task TestEventListeners() { using (ProgressV2 progress = new ProgressV2("p3", 200)) { var progressEventTriggered = false; progress.ProgressChanged += (o, newValue) => { Log.e(JsonWriter.AsPrettyString(o)); Assert.Equal(100, newValue); progressEventTriggered = true; }; await TaskV2.Run(() => { ((IProgress <double>)progress).Report(100); Assert.False(progressEventTriggered); Assert.Equal(100, progress.GetCount()); Assert.Equal(50, progress.percent); }); Assert.Equal(100, progress.GetCount()); Assert.Equal(50, progress.percent); // The progress callback is dispatched using the SynchronizationContext // of the constructor, so it will have some delay before being called: Assert.False(progressEventTriggered); await TaskV2.Delay(50); // Wait for progress update to be invoked Assert.True(progressEventTriggered); } }
public static async Task SimulateManyChangesInModel(DataStore <CellsModel> store, int nrOfChanges = 100) { var t = Log.MethodEnteredWith("nrOfChanges=" + nrOfChanges); var random = new Random(); var ops = new string[] { "+", "-", "*", "/" }; var progress = ProgressUi.NewProgress(nrOfChanges); for (int i = 0; i < nrOfChanges; i++) { progress.IncrementCount(); try { int column = random.Next(1, 26 * 2); int row = random.Next(1, 26 * 2); string rndFormula = RndVar(random, store) + random.NextRndChild(ops) + RndVar(random, store); store.Dispatch(new MyActions.SetCell(CellPos.ToColumnName(column), row, rndFormula)); } catch (Exception e) { Log.e(e); } if (i % 10 == 0) { await TaskV2.Delay(20); } // Every few mutations wait to let the UI catch UI } progress.SetComplete(); Log.MethodDone(t); }
private static Task ConfirmButtonClicked(GameObject targetView, string confirmButtonId) { return(targetView.GetLinkMap().Get <Button>(confirmButtonId).SetOnClickAction(async delegate { Toast.Show("Saving.."); await TaskV2.Delay(500); // Wait for potential pending throttled actions to update the model })); }
private async Task SomeAsyncTask1(CancellationToken cancelRequest) { var t = Log.MethodEntered(); await TaskV2.Delay(500); Log.MethodDone(t); }
public async Task TestThrottledDebounce5() { int counter = 0; int delayInMs = 200; Func <object, Task> originalFunction = async(object param) => { Assert.Equal("good", param); counter++; await TaskV2.Delay(delayInMs * 4); }; var wrappedFunc = originalFunction.AsThrottledDebounce(10, skipFirstEvent: true); { var t = Stopwatch.StartNew(); var task = wrappedFunc("good"); Assert.Equal(0, counter); await task; Assert.Equal(1, counter); Assert.True(t.ElapsedMilliseconds > delayInMs * 2, "ElapsedMilliseconds=" + t.ElapsedMilliseconds); } { var b = wrappedFunc("bad"); wrappedFunc("bad"); var t = wrappedFunc("good"); Assert.Equal(1, counter); await TaskV2.Delay(delayInMs); Assert.Equal(2, counter); Assert.False(t.IsCompleted); await t; Assert.True(b.IsCompleted); Assert.False(b.IsCompletedSuccessfull()); Assert.False(b.IsCompletedSuccessfully); } }
public async Task DownloadTest4_LoadOnlyImageInfo() { var pixels = 4500; // 5k x 5k is the max that picsum will serve var h = pixels; var w = pixels; var timingForFullImage = Log.MethodEntered("Load full image"); var fullImage = await new Uri("https://picsum.photos/" + w + "/" + h).SendGET().GetResult <Stream>(); var info2 = await ImageLoader.GetImageInfoFrom(fullImage); fullImage.Dispose(); Assert.Equal(h, info2.Height); Assert.Equal(w, info2.Width); Log.MethodDone(timingForFullImage); // Wait some time before sending the next request to the picsum server to not get rejected: await TaskV2.Delay(1000); var timingForImageInfoOny = Log.MethodEntered("Load only first bytes"); var stream = await new Uri("https://picsum.photos/" + w + "/" + h).SendGET().GetResult <Stream>(); var firstBytes = await CopyFirstBytes(stream, bytesToCopy : 2000); stream.Dispose(); var info = await ImageLoader.GetImageInfoFrom(firstBytes); firstBytes.Dispose(); Assert.Equal(w, info.Width); Assert.Equal(h, info.Height); Log.MethodDone(timingForImageInfoOny); var xTimesFaster = 2; // Loading only the image info should be at least this factor faster then loading the full image string e = timingForImageInfoOny + " was not faster then " + timingForFullImage; Assert.True(timingForImageInfoOny.ElapsedMilliseconds * xTimesFaster < timingForFullImage.ElapsedMilliseconds, e); }
public async Task TestThrottledDebounce6() { int counter = 0; Func <Task> originalFunction = () => { counter++; throw new NotImplementedException(); }; var wrappedFunc = originalFunction.AsThrottledDebounce(10); { Assert.Equal(0, counter); var t = wrappedFunc(); Assert.Equal(1, counter); Assert.True(t.IsFaulted); await Assert.ThrowsAsync <NotImplementedException>(() => t); } { Assert.Equal(1, counter); wrappedFunc(); var t = wrappedFunc(); Assert.Equal(1, counter); Assert.False(t.IsFaulted); await TaskV2.Delay(50); Assert.Equal(2, counter); Assert.True(t.IsFaulted); await Assert.ThrowsAsync <NotImplementedException>(() => t); } }
private async Task WaitForRequestToFinish() { while (!request.isDone && !request.isHttpError && !request.isNetworkError) { await TaskV2.Delay(10); } }
public async Task ThrottledDebounceExample2() { int counter = 0; bool allWereGood = true; Action <string> action = (myStringParam) => { // Make sure the action is never called with "bad" being passed: if (myStringParam != "good") { allWereGood = false; } Interlocked.Increment(ref counter); }; // Make the action throttled / debounced: action = action.AsThrottledDebounce(delayInMs: 50); // Call it multiple times with less then 50ms between the calls: action("good"); // The first call will always be passed through action("bad"); // This one will be delayed and not called because of the next: action("good"); // This will be delayed for 50ms and then triggered because no additional call follows after it // Wait a little bit until the action was triggered at least 2 times: for (int i = 0; i < 50; i++) { await TaskV2.Delay(200); if (counter >= 2) { break; } } Assert.Equal(2, counter); Assert.True(allWereGood); }
public IEnumerator TestTaskCancel() { var timing = Log.MethodEntered("TestTaskCancel"); var counter = 0; var task1 = TaskRunner.instance.RunInBackground(async(c) => { Assert.IsFalse(MainThread.isMainThread); for (int i = 0; i < int.MaxValue; i++) { await TaskV2.Delay(10); counter++; c.ThrowIfCancellationRequested(); } }); yield return(new WaitForSeconds(0.2f)); task1.cancelTask(); yield return(task1.AsCoroutine()); Assert.IsTrue(task1.task.IsCanceled); Assert.IsTrue(counter > 10, "counter=" + counter); Assert.IsTrue(counter < 50, "counter=" + counter); Log.MethodDone(timing); }
public async Task TestOnError() { { var errorHandled = false; await SomeAsyncFailingTask1().OnError(async _ => { await TaskV2.Delay(5); errorHandled = true; // error can be rethrown here }); Assert.True(errorHandled); } { var errorHandled = false; var result = await SomeAsyncFailingTask2().OnError(async _ => { await TaskV2.Delay(5); errorHandled = true; return("handled"); }); Assert.Equal("handled", result); Assert.True(errorHandled); } { // The error can be rethrown in OnError handler after reacting to it: await Assert.ThrowsAsync <AggregateException>(async() => { await SomeAsyncFailingTask1().OnError(async error => { await TaskV2.Delay(5); throw error; }); }); } }
private static async Task TestAsyncActions(IDataStore <MyAppState1> store) { var t = Log.MethodEntered("TestAsyncActions"); Assert.Null(store.GetState().currentWeather); // Create an async action and dispatch it so that it is executed by the thunk middleware: var a = store.Dispatch(NewAsyncGetWeatherAction()); Assert.True(a is Task, "a=" + a.GetType()); if (a is Task delayedTask) { await delayedTask; } Assert.NotEmpty(store.GetState().currentWeather); store.Dispatch(new ActionLogoutUser()); Assert.Null(store.GetState().user); // Another asyn task example with an inline lambda function: Func <Task> asyncLoginTask = async() => { await TaskV2.Delay(100); // Simulate that the login would talk to a server and take some time // Here the user would be logged into the server and returned to the client to store it: store.Dispatch(new ActionLoginUser() { newLoggedInUser = new MyUser1("Karl") }); }; // Since the async action uses Func<Task> the returned object can be awaited on: await(store.Dispatch(asyncLoginTask) as Task); Assert.NotNull(store.GetState().user); Log.MethodDone(t); }
public async Task ExampleUsage1() { Log.d("Now testing TaskV2.Run"); await TaskV2.Run(() => { var t = Log.MethodEntered("1"); TaskV2.Delay(100).ContinueWithSameContext(delegate { Log.MethodDone(t); }); }); Log.d("Now testing async TaskV2.Run"); await TaskV2.Run(async() => { var t = Log.MethodEntered("2"); await TaskV2.Delay(100); Log.MethodDone(t); }); Log.d("Now testing async TaskV2.Run with return value"); var result = await TaskV2.Run(async() => { var t = Log.MethodEntered("3"); await TaskV2.Delay(100); Log.MethodDone(t); return("3"); }); Assert.Equal("3", result); }
public async Task <HttpResponseMessage> SendAsync(HttpMethod method) { HttpClientHandler handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; AddAllCookiesToRequest(handler); client = new HttpClient(handler); await TaskV2.Delay(5); // Wait so that the created RestRequest can be modified before its sent httpMethod = "" + method; client.AddRequestHeaders(requestHeaders); var message = new HttpRequestMessage(method, uri); if (httpContent != null) { message.Content = httpContent; } if (OnBeforeSend != null) { await OnBeforeSend(client, message); } request = client.SendAsync(message, sendAsyncCompletedAfter); var result = await request; var serverUtcDate = result.Headers.Date; if (serverUtcDate != null) { EventBus.instance.Publish(DateTimeV2.SERVER_UTC_DATE, uri, serverUtcDate.Value.DateTime); } return(result); }
private async Task SomeAsyncTask1() { var t = Log.MethodEntered(); await TaskV2.Delay(500); Log.MethodDone(t); }
private async Task RunWaitForNoVisualChangeInSceneTest() { AssertVisually assertVisually = NewAssertVisuallyInstance("Ui19_RunVisualRegression_ExampleUsage3"); Task visualChangeMonitorTask = assertVisually.WaitForNoVisualChangeInScene(); AssertV2.IsFalse(visualChangeMonitorTask.IsCompleted, "visualChangeMonitorTask.IsCompleted"); gameObject.AddChild(await NewUiFor <MyUserModelv1>()); // Change the UI await TaskV2.Delay(200); // After 200 ms the monitorTask should still be checking: AssertV2.IsFalse(visualChangeMonitorTask.IsCompleted, "visualChangeMonitorTask.IsCompleted"); gameObject.AddChild(await NewUiFor <MyUserModelv2>()); // Change the UI again await TaskV2.Delay(200); // After 200 ms the monitorTask should still be checking: AssertV2.IsFalse(visualChangeMonitorTask.IsCompleted, "visualChangeMonitorTask.IsCompleted"); gameObject.AddChild(await NewUiFor <MyUserModelv1>()); // Change the UI again await TaskV2.Delay(200); // After 200 ms the monitorTask should still be checking: AssertV2.IsFalse(visualChangeMonitorTask.IsCompleted, "visualChangeMonitorTask.IsCompleted"); await TaskV2.Delay(2000); // Dont change the UI for 2 sec // Now the change monitor task should have completed since the sceen did not change for 2 sec: AssertV2.IsTrue(visualChangeMonitorTask.IsCompleted, "visualChangeMonitorTask.IsCompleted"); await visualChangeMonitorTask; // await the task in case there was an exception }
public async Task TestRunRepeated1() // Aligned with the coroutine test TestExecuteRepeated1 { var counter = 0; var cancel = new CancellationTokenSource(); { #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed TaskV2.RunRepeated(async() => { await TaskV2.Delay(1); counter++; return(counter < 3); // stop repeated execution once 3 is reached }, delayInMsBetweenIterations: 300, cancelToken: cancel.Token, delayInMsBeforeFirstExecution: 200); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } { // while the repeated task is running check over time if the counter increases: await TaskV2.Delay(100); Assert.Equal(0, counter); await TaskV2.Delay(200); Assert.Equal(1, counter); await TaskV2.Delay(300); Assert.Equal(2, counter); await TaskV2.Delay(300); Assert.Equal(3, counter); await TaskV2.Delay(300); Assert.Equal(3, counter); } cancel.Cancel(); }
public async Task TestDefaultAppFlowImplementation() { var tracker = new MyAppFlowTracker2(new InMemoryKeyValueStore().GetTypeAdapter <AppFlowEvent>()); AppFlow.AddAppFlowTracker(tracker); Log.MethodEntered(); // This will internally notify the AppFlow instance Assert.NotEmpty(await tracker.store.GetAllKeys()); var s = StopwatchV2.StartNewV2(); for (int i = 0; i < 20; i++) { await TaskV2.Delay(500); if ((await tracker.store.GetAllKeys()).Count() == 0) { break; } } Assert.True(s.ElapsedMilliseconds < 5000, "s.ElapsedMilliseconds=" + s.ElapsedMilliseconds); Assert.Empty(await tracker.store.GetAllKeys()); // Make sure the DefaultAppFlowImpl itself does not create more events while sending the existing ones: for (int i = 0; i < 10; i++) { await TaskV2.Delay(100); var c1 = tracker.eventsThatWereSent.Count; await TaskV2.Delay(100); var c2 = tracker.eventsThatWereSent.Count; Assert.Equal(c1, c2); } }
public async Task TestThrottledDebounce5() { int delayInMs = 200; Func <object, Task> originalFunction = async(object sender) => { Assert.Equal("good", sender); await TaskV2.Delay(delayInMs * 4); }; var wrappedFunc = originalFunction.AsThrottledDebounce(10); var t = Stopwatch.StartNew(); var task = wrappedFunc("good"); await TaskV2.Delay(delayInMs); Assert.Null(wrappedFunc("bad")); Assert.Null(wrappedFunc("bad")); Assert.Null(wrappedFunc("bad")); await task; await TaskV2.Delay(delayInMs); task = wrappedFunc("good"); Assert.NotNull(task); Assert.Null(wrappedFunc("bad")); Assert.Null(wrappedFunc("bad")); Assert.Null(wrappedFunc("bad")); await task; Assert.True(t.ElapsedMilliseconds > 200, "ElapsedMilliseconds=" + t.ElapsedMilliseconds); }
protected override async Task <bool> SendEventToExternalSystem(AppFlowEvent appFlowEvent) { Log.d("SendEventToExternalSystem called with appFlowEvent=" + JsonWriter.AsPrettyString(appFlowEvent)); await TaskV2.Delay(10); // Simulate that sending the event to an analytics server takes time eventsThatWereSent.Add(appFlowEvent); return(true); }