рд╣рд╛рдп рд╣рдорд░! рдФрд░ рдЗрд╕рд▓рд┐рдП, рднрд╛рд▓реЗ рдХреЗ рдЪреМрджрд╣рд╡реЗрдВ рджрд┐рди, рдореИрдВрдиреЗ рд╕рд░рд▓ рдСрдирд▓рд╛рдЗрди рд╢реВрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдЧреЗрдо рд╕рд░реНрд╡рд░ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╕реНрдкрд░реНрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рддрд░рд┐рдд рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреЗ рдПрдХ рд╡рд┐рд╖рдп рдХреЗ рд▓рд┐рдПред рдЪрдХреНрд░ рдХреЗ рдЗрд╕ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЕрднрд┐рдиреЗрддрд╛ рдХреНрдпрд╛ рд╣реИрдВ (рдСрд░рд▓рд┐рдпрдиреНрд╕ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЕрдирд╛рдЬ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рдФрд░ рдЙрдирдХреЗ рдХрд╛рдо рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрддред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЕрднреА рднреА рдСрд░рд▓рд┐рдпрдиреНрд╕ рдХреЗ рдмрд┐рдирд╛ рдШрд░-рдирд┐рд░реНрдорд┐рдд рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реВрдВред рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдПрдХ рдЬрд╣рд╛рдЬ рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд╣рддреЗ рд╣реИрдВ, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рддреИрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдХрд╛рдЧрдЬ рдХреА рдирд╛рд╡ рдХреНрдпреЛрдВ рддреИрд░рддреА рд╣реИред рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИредрд╕рд╛рдордЧреНрд░реА
- рдПрдордПрд╕ рдСрд░рд▓рд┐рдпрдиреНрд╕ рдкрд░ рдЧреЗрдо рд╕рд░реНрд╡рд░ - рднрд╛рдЧ 1: рдЕрднрд┐рдиреЗрддрд╛ рдХреНрдпрд╛ рд╣реИрдВ
рдЕрднрд┐рдиреЗрддрд╛
рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рдПрдХ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рдЗрдХрд╛рдИ рд╣реИ рдЬреЛ рдкреНрд░рд╛рдкреНрдд рд╕рдВрджреЗрд╢ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ, рдПрдХ рд╕рд╛рде рдХрд░ рд╕рдХрддрд╛ рд╣реИ:рдЕрдиреНрдп рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рд╕рдВрджреЗрд╢реЛрдВ рдХреА рдПрдХ рд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИ ;рдирдП рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рдПрдХ рд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдмрдирд╛рдПрдВ;рдЙрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдЧрд▓реЗ рдкреНрд░рд╛рдкреНрдд рд╕рдВрджреЗрд╢ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛редрдпрд╣ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЕрдиреБрдХреНрд░рдо рдореМрдЬреВрдж рд╣реИ, рдФрд░ рдЙрди рд╕рднреА рдХреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрд╣рдо рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдХреБрдЫ рд╕рдВрджреЗрд╢ (рдЯреАрдореНрд╕ рдпрд╛ рдЗрд╡реЗрдВрдЯреНрд╕) рднреЗрдЬрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣ рдЦреБрдж рджреВрд╕рд░реЛрдВ рдХреЛ рднреА рдпрд╣реА рд╕рдВрджреЗрд╢ рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИред рдЪреИрдирд▓реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╛рди рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╡реЗ рдЪреИрдирд▓ рд╕реЗ рдХреБрдЫ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реБрдП рдЪреИрдирд▓ рдХреЛ рдХреБрдЫ рдбреЗрдЯрд╛ рднреЗрдЬрддреЗ рд╣реИрдВредрдЙрджрд╛рд╣рд░рдг
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб: class Program
{
interface IMessage { }
class IncrementCommand : IMessage { }
class TellCountCommand : IMessage { }
class SaidCountEvent : IMessage
{
public int Count { get; }
public int ActorId { get; }
public SaidCountEvent(int count, int actorId)
{
Count = count;
ActorId = actorId;
}
}
class WriteMessageCommand : IMessage
{
public string Message { get; }
public WriteMessageCommand(string message)
{
Message = message;
}
}
static Task CreateCounterActor(
BlockingCollection<IMessage> output,
BlockingCollection<IMessage> input,
int id
)
{
return Task.Run(() =>
{
var count = 0;
while (true)
{
var m = input.Take();
if (m is IncrementCommand)
count++;
if (m is TellCountCommand)
output.Add(new SaidCountEvent(count, id));
}
});
}
static Task CreateWriterActor(BlockingCollection<IMessage> input)
{
return Task.Run(() =>
{
while (true)
{
var m = input.Take();
if (m is WriteMessageCommand write)
Console.WriteLine(write.Message);
if (m is SaidCountEvent sc)
Console.WriteLine(
$"Counter {sc.Count} {sc.ActorId}"
);
}
});
}
static void Main(string[] args)
{
var writerInput = new BlockingCollection<IMessage>();
var firstInput = new BlockingCollection<IMessage>();
var secondInput = new BlockingCollection<IMessage>();
var writer = CreateWriterActor(writerInput);
var firstCounter = CreateCounterActor(writerInput, firstInput, 1);
var secondCounter = CreateCounterActor(writerInput, secondInput, 2);
for (int i = 0; i < 5; i++)
{
firstInput.Add(new IncrementCommand());
}
for (int i = 0; i < 9; i++)
{
secondInput.Add(new IncrementCommand());
}
firstInput.Add(new TellCountCommand());
secondInput.Add(new TellCountCommand());
writerInput.Add(new WriteMessageCommand(" Main"));
Console.ReadLine();
}
}
- рд╡рд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рд╣рдо рдЙрди рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЕрднрд┐рдиреЗрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдпрд╛ рднреЗрдЬрддрд╛ рд╣реИ:
interface IMessage { }
- рд╡рд╣ рдХрдорд╛рдВрдб рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдЕрдкрдирд╛ рдХрд╛рдЙрдВрдЯрд░ (рдЖрдВрддрд░рд┐рдХ рд╕реНрдерд┐рддрд┐) рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ:
class IncrementCommand : IMessage { }
- рд╡рд╣ рдХрдорд╛рдВрдб рдЬрд┐рд╕рдХреА рдорджрдж рд╕реЗ рд╣рдо рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдЕрдкрдиреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ (рдХрд╛рдЙрдВрдЯрд░) рджреВрд╕рд░реЛрдВ рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ:
class TellCountCommand : IMessage { }
- рдПрдХ рдШрдЯрдирд╛ рдЬреЛ рдЕрдиреНрдп рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдмрддрд╛рддреА рд╣реИ рдХрд┐ рдЕрднрд┐рдиреЗрддрд╛ рдиреЗ рд╕рднреА рдХреЛ рдЕрдкрдиреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ (рдХрд╛рдЙрдВрдЯрд░) рдмрддрд╛рдИ рд╣реИред рдЬрдм TellCountCommand рдЖрджреЗрд╢ рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЙрддреНрдкрдиреНрди:
class SaidCountEvent : IMessage
{
public int Count { get; }
public int ActorId { get; }
public SaidCountEvent(int count, int actorId)
{
Count = count;
ActorId = actorId;
}
}
рдЧрдгрдирд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рдХрд╛рдЙрдВрдЯрд░ рдкрд░ рдЕрдм рдПрдХреНрдЯрд░рдЖрдИрдЖрд░рдбреА рдХреЗ рдмрд░рд╛рдмрд░ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдХрд┐рддрдирд╛ рдбрд╛рдпрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
- рдпрд╣ рдХрдорд╛рдВрдб рдПрдХреНрдЯрд░ рд╕реЗ рдХрд╣рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдВрджреЗрд╢ рдХреЛ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдВ:
class WriteMessageCommand : IMessage
{
public string Message { get; }
public WriteMessageCommand(string message)
{
Message = message;
}
}
- рдХрд╛рдЙрдВрдЯрд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рдЙрджрд╛рд╣рд░рдг рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ:
static Task CreateCounterActor(
//
BlockingCollection<IMessage> output,
//
BlockingCollection<IMessage> input,
//
int id
)
{
return Task.Run(() =>
{
var count = 0;
while (true)
{
var m = input.Take();
if (m is IncrementCommand)
count++;
if (m is TellCountCommand)
output.Add(new SaidCountEvent(count, id));
}
});
}
- рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдмрд╕ рдХрдВрд╕реЛрд▓ рдХреЛ рд╕рдВрджреЗрд╢ рд▓рд┐рдЦрддрд╛ рд╣реИ:
static Task CreateWriterActor(BlockingCollection<IMessage> input)
{
return Task.Run(() =>
{
while (true)
{
var m = input.Take();
if (m is WriteMessageCommand write)
Console.WriteLine(write.Message);
if (m is SaidCountEvent sc)
Console.WriteLine(
$"Counter {sc.Count} {sc.ActorId}"
);
}
});
}
static void Main(string[] args)
{
var writerInput = new BlockingCollection<IMessage>();
var firstInput = new BlockingCollection<IMessage>();
var secondInput = new BlockingCollection<IMessage>();
var writer = CreateWriterActor(writerInput);
var firstCounter = CreateCounterActor(writerInput, firstInput, 1);
var secondCounter = CreateCounterActor(writerInput, secondInput, 2);
for (int i = 0; i < 5; i++)
{
firstInput.Add(new IncrementCommand());
}
for (int i = 0; i < 9; i++)
{
secondInput.Add(new IncrementCommand());
}
firstInput.Add(new TellCountCommand());
secondInput.Add(new TellCountCommand());
writerInput.Add(new WriteMessageCommand(" Main"));
Console.ReadLine();
}
рдареАрдХ рд╣реИ, рддрд╛рдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реБрдВрджрд░ рд╣реЛ рдФрд░ рдСрд░рд▓рд┐рдпрдиреНрд╕ рд╕реЗ рдЧреНрд░реЗрд▓ (рдЕрднрд┐рдиреЗрддрд╛) рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдВ, рдЖрдЗрдП рд╣рдорд╛рд░реЗ рдЪреЗрд╣рд░реЗ рдкрд░ рдПрдХ рдЖрд╡рд░рдг рдмрдирд╛рдПрдВ: public interface ICounterActor
{
void Increment();
void TellCount();
}
public class CounterActor : ICounterActor
{
private readonly Task _taks;
private readonly BlockingCollection<IMessage> _input;
private readonly BlockingCollection<IMessage> _output;
public CounterActor(BlockingCollection<IMessage> output)
{
_input = new BlockingCollection<IMessage>(); ;
_output = output;
_taks = Task.Run(() =>
{
var count = 0;
while (true)
{
var m = _input.Take();
if (m is IncrementCommand)
count++;
if (m is TellCountCommand)
_output.Add(new SaidCountEvent(count, _taks.Id));
}
});
}
public void Increment()
{
_input.Add(new IncrementCommand());
}
public void TellCount()
{
_input.Add(new TellCountCommand());
}
}
рдпрд╣рд╛рдВ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдорд╛рд░реЗ рдЕрднрд┐рдиреЗрддрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╡рд╛рдВрдЫрд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдирдП рд╕рдВрджреЗрд╢ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдзрд╛рдЧреЗ рдореЗрдВ рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рд╣реИ, рд╣рд░ рдХрд┐рд╕реА рд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдзрд╛рдЧрд╛, рдЗрд╕рдХреЗ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИред рдПрдХ рдФрд░ рдЕрднрд┐рдиреЗрддрд╛ рд╕рд┐рд░реНрдл рд╕рд╛рдВрддреНрд╡рдирд╛ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЖрдЗрдП рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рдиреЗрддрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрди рджрд╕ рдЦрд┐рд▓рд╛рдбрд╝рд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд╡рд░реНрддрдорд╛рди рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ, рд╕реНрд╡рд╛рд╕реНрдереНрдп рдФрд░ рдордиреНрдирд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдЦреЗрд▓ рд░рд╣реЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдореЗрдВ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рдеред рд╣рдо рджреВрд╕рд░реЛрдВ рдХреЛ рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╣реИрдВ рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдиреБрдХрд╕рд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреВрд╕рд░реЛрдВ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХреМрд╢рд▓ рдпрд╛ рд╣рдорд╛рд░реЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиред