Процесс Erlang аналогичен работающему методу параллельно, но переменная erlang может быть привязана только один раз, поэтому она является потокобезопасной, которая не находится в C#.
так что вам нужно две вещи в C#, потокобезопасность и параллельность.
C# имеет System.Threading.Task, вы можете запускать множество задач в vm. C# vm будет планировать эту задачу в разных рабочих потоках.
Но задача не потокобезопасна, вам нужно создать класс под названием «Актер» и поставить государство в Актер.
Актер имеет System.Threading.SynchronizationContext и многие методы async, например.
class Actor {
public SynchronizationContext _context;
private int value1;
private Dictionary<> xxx;
private List<> xxx;
public async Task Method1() {
await _context;
doSomething();
}
}
Когда другие актеры называют методы асинхронных в этом актере, он будет создавать задачу, и задача будет планироваться VM.
Вам также необходимо реализовать ожидаемый и потокобезопасный SynchronizationContext.
Это контекст, безопасный для потоков.
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;
}
}
сделать SynchroniztionContext awaitable
public static class SynchroniztionContextExtensions
{
public static SynchronizationContextAwaiter GetAwaiter (this SynchronizationContext context)
{
if(context == null) throw new ArgumentNullException("context");
return new SynchronizationContextAwaiter(context);
}
}
Awaiter для 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(){}
}
тогда вы получите класс Actor с задачей и поточно, которые, как процесс в Erlang.
Полезно, если OP не фокусируется на определенном языке. –
Разве это не безопасно интерпретировать любую ссылку на Аксум как «Woohoo! Все идет, детка!» :) –