Erlang-Prozess ist wie Running-Methode parallel, aber Erlang-Variable kann nur einmal gebunden werden, so ist es Thread sicher, die nicht in C# ist.
so brauchen Sie zwei Dinge in C#, Thread sicher und parallel.
C# hat System.Threading.Task, Sie können viele Aufgaben in VM ausführen. C# vm plant diese Aufgabe in verschiedenen Arbeitsthreads.
Aber Aufgabe ist nicht threadsicher, Sie müssen eine Klasse namens Actor machen und den Status privat in den Actor legen.
Der Actor verfügt über einen System.Threading.SynchronizationContext und viele asynchrone Methoden wie diesen.
class Actor {
public SynchronizationContext _context;
private int value1;
private Dictionary<> xxx;
private List<> xxx;
public async Task Method1() {
await _context;
doSomething();
}
}
Wenn andere Schauspieler von der Asynchron-Methode in diesem Schauspieler nennen, wird es eine Aufgabe erstellen, und die Aufgabe von vm geplant wird.
Sie müssen auch einen erwarteten und Thread-sicheren SynchronizationContext implementieren.
Dies ist ein threadsicherer Kontext.
public class ActorSynchronizationContext : SynchronizationContext
{
private readonly SynchronizationContext _subContext;
private readonly ConcurrentQueue<Action> _pending = new ConcurrentQueue<Action>();
private int _pendingCount;
public ActorSynchronizationContext(SynchronizationContext context = null)
{
this._subContext = context ?? new SynchronizationContext();
}
public override void Post(SendOrPostCallback d, object state)
{
if (d == null) {
throw new ArgumentNullException("SendOrPostCallback");
}
_pending.Enqueue(() => d(state));
if (Interlocked.Increment(ref _pendingCount) == 1)
{
try
{
_subContext.Post(Consume, null);
}
catch (Exception exp)
{
LogHelper.LogUnhandleException(exp.ToString());
}
}
}
private void Consume(object state)
{
var surroundContext = Current;
SetSynchronizationContext(this);
do
{
Action a;
_pending.TryDequeue(out a);
try
{
a.Invoke();
}
catch (Exception exp)
{
//Debug.LogError(exp.ToString());
LogHelper.LogUnhandleException(exp.ToString());
}
} while (Interlocked.Decrement(ref _pendingCount) > 0);
SetSynchronizationContext(surroundContext);
}
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException();
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
machen SynchroniztionContext awaitable
public static class SynchroniztionContextExtensions
{
public static SynchronizationContextAwaiter GetAwaiter (this SynchronizationContext context)
{
if(context == null) throw new ArgumentNullException("context");
return new SynchronizationContextAwaiter(context);
}
}
Erwartenden für SynchronizationContext
public sealed class SynchronizationContextAwaiter : INotifyCompletion
{
private readonly SynchronizationContext _context;
public SynchronizationContextAwaiter(SynchronizationContext context)
{
if(context == null) throw new ArgumentNullException("context");
_context = context;
}
public bool IsCompleted {
get
{
//已经在当前上下文里面了,就不需要再次切换上下文
return SynchronizationContext.Current == _context;
}
}
/// <summary>
/// 将Action 任务调度到 _context 控制的线程里面去执行
///
/// var temp = e.GetAwaiter();
/// </summary>
/// <param name="action">Action.</param>
public void OnCompleted(Action action) {
_context.Post(x=>action(), null);
}
public void GetResult(){}
}
dann Sie eine Schauspieler-Klasse mit Aufgabe bekommen und sicher Threads, wie Prozess in erlang.
Nützlich, vorausgesetzt, das OP ist nicht auf eine bestimmte Sprache ausgerichtet. –
Ist es nicht grundsätzlich sicher, irgendeinen Hinweis auf Axum als "Woohoo! Alles geht, Baby!" :) –