Skip to content

Instantly share code, notes, and snippets.

@Denis535
Last active June 21, 2022 20:04
Show Gist options
  • Save Denis535/03c666fd5ecc39ca527e2d7d5c31fbdb to your computer and use it in GitHub Desktop.
Save Denis535/03c666fd5ecc39ca527e2d7d5c31fbdb to your computer and use it in GitHub Desktop.
namespace ConsoleApp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Threading;
class Program {
private static async Task Main(string[] args) {
var game = new Game();
new Timer( i => game.ActionAsync().Wait(), null, 0, 3000 );
game.Run();
}
}
public class Game {
private GameTaskScheduler TaskScheduler { get; } = new GameTaskScheduler();
public Game() {
}
// Run game loop
public void Run() {
while (true) {
TaskScheduler.Execute();
// Game logic
Console.WriteLine( "Update: {0:00}", Environment.CurrentManagedThreadId );
Thread.Sleep( 1000 );
}
}
// User action
public async Task ActionAsync() {
await SwitchToMainThread(); // Switch to game thread
Console.WriteLine( "Action: {0:00}", Environment.CurrentManagedThreadId );
}
// Utils
public AwaitExtensions.TaskSchedulerAwaitable SwitchToMainThread() {
return TaskScheduler.SwitchTo();
}
}
// todo: Can I do it without custom TaskScheduler?
internal class GameTaskScheduler : TaskScheduler {
private ConcurrentQueue<Task> Tasks { get; } = new ConcurrentQueue<Task>();
public override int MaximumConcurrencyLevel => 1;
public void Execute() {
while (Tasks.TryDequeue( out var task )) {
TryExecuteTask( task );
}
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) {
return false;
}
protected override void QueueTask(Task task) {
Tasks.Enqueue( task );
}
protected sealed override bool TryDequeue(Task task) {
return false;
}
protected override IEnumerable<Task>? GetScheduledTasks() {
return Tasks.ToArray();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment