एरलांग प्रक्रिया समानांतर तरीके से चलने की विधि की तरह है, लेकिन erlang चर केवल एक बार बाध्य किया जा सकता है, इसलिए यह थ्रेड सुरक्षित है जो सी # में नहीं है।
इसलिए आपको सी #, थ्रेड सुरक्षित और समांतर में दो चीजों की आवश्यकता है।
सी # में सिस्टम है। थ्रेडिंग टास्क, आप वीएम में कई कार्य चला सकते हैं। सी # वीएम इन कार्यों को विभिन्न कामकाजी धागे में शेड्यूलर करेगा।
लेकिन कार्य धागा सुरक्षित नहीं है, आपको अभिनेता नामक एक वर्ग बनाने की जरूरत है, और अभिनेता में राज्य को निजी रखना है।
अभिनेता के पास एक सिस्टम है। थ्रेडिंग। सिंक्रनाइज़ेशन कॉन्टेक्स्ट, और इस तरह के कई async तरीके।
class Actor {
public SynchronizationContext _context;
private int value1;
private Dictionary<> xxx;
private List<> xxx;
public async Task Method1() {
await _context;
doSomething();
}
}
अन्य अभिनेता इस अभिनेता में async विधि कॉल करते हैं, यह भी कार्य बना होगा, और काम वीएम द्वारा अनुसूचित होगा।
आपको एक प्रतीक्षा करने योग्य और थ्रेड सुरक्षित सिंक्रनाइज़ेशन कॉन्टेक्स्ट को भी लागू करने की आवश्यकता है।
यह एक धागा सुरक्षित संदर्भ है।
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
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(){}
}
के लिए awaitable बनाने के जो erlang में प्रक्रिया की तरह।
उपयोगी, मानते हुए कि ओपी किसी विशेष भाषा पर केंद्रित नहीं है। –
क्या यह आम तौर पर एक्सम के किसी भी संदर्भ को समझने के लिए सुरक्षित नहीं है "वाहू! कुछ भी जाता है, बच्चे!" :) –