C# 了解奥尔良谷物的单螺纹性质
我在奥尔良有一个客户机和一个谷物的以下代码片段(尽管在奥尔良开发的推荐方法是等待任务,但以下代码在某些时候并非纯粹出于实验目的而等待)C# 了解奥尔良谷物的单螺纹性质,c#,.net-core,async-await,actor,orleans,C#,.net Core,Async Await,Actor,Orleans,我在奥尔良有一个客户机和一个谷物的以下代码片段(尽管在奥尔良开发的推荐方法是等待任务,但以下代码在某些时候并非纯粹出于实验目的而等待) // client code while(true) { Console.WriteLine("Client giving another request"); double temperature = random.NextDouble() * 40; var grain = client.GetGrain<ITemp
// client code
while(true)
{
Console.WriteLine("Client giving another request");
double temperature = random.NextDouble() * 40;
var grain = client.GetGrain<ITemperatureSensorGrain>(500);
Task t = sensor.SubmitTemperatureAsync((float)temperature);
Console.WriteLine("Client Task Status - "+t.Status);
await Task.Delay(5000);
}
// ITemperatureSensorGrain code
public async Task SubmitTemperatureAsync(float temperature)
{
long grainId = this.GetPrimaryKeyLong();
Console.WriteLine($"{grainId} outer received temperature: {temperature}");
Task x = SubmitTemp(temperature); // SubmitTemp() is another function in the same grain
x.Ignore();
Console.WriteLine($"{grainId} outer received temperature: {temperature} exiting");
}
public async Task SubmitTemp(float temp)
{
for(int i=0; i<1000; i++)
{
Console.WriteLine($"Internal function getting awaiting task {i}");
await Task.Delay(1000);
}
}
//客户端代码
while(true)
{
Console.WriteLine(“提出另一请求的客户”);
双温=随机。下一个双温()*40;
var grain=client.GetGrain(500);
任务t=传感器。提交温度异步((浮动)温度);
Console.WriteLine(“客户端任务状态-”+t.Status);
等待任务。延迟(5000);
}
//ItemTemperatureSensorGrain代码
公共异步任务提交温度异步(浮动温度)
{
long grainId=this.GetPrimaryKeyLong();
WriteLine($“{grainId}外部接收温度:{temperature}”);
Task x=SubmitTemp(temperature);//SubmitTemp()是同一粒度中的另一个函数
x、 忽略();
WriteLine($“{grainId}外部接收温度:{temperature}正在退出”);
}
公共异步任务SubmitTemp(浮点温度)
{
对于(int i=0;iQuestion 1):所描述的执行流是否准确地表示了正在发生的事情?
你的描述在我看来大致正确,但这里有几点更好:
- 是否存在线程池是一个实现细节
- “轮次”是在激活的
TaskScheduler
上计划的每个同步工作部分
- 因此,每当执行必须返回到
任务调度器时,循环就结束了
- 这可能是因为未同步完成的
await
被命中,或者用户根本没有使用await
,正在使用ContinueWith
或自定义等待项进行编程
- 回合可以从非顶级方法结束,例如,如果代码更改为
等待提交(x)
而不是。忽略()
它,则回合将在任务.Delay(…)
在提交(x)
内命中时结束
问题2:示例程序是否证明违反了单线程保证?
不,在给定时间只有一个线程执行grain的代码。但是,该“线程”必须在激活的TaskScheduler
上调度的各种任务之间分配时间。也就是说,您永远不会暂停进程并发现两个线程正在执行grain的代码同时,
就运行时而言,当任务
(或其他可等待类型)完成时,消息处理结束从顶级方法返回的消息完成。在此之前,不会计划在激活时执行新消息。始终允许从方法生成的后台任务与其他任务交错
.NET允许将子任务附加到其父任务。在这种情况下,父任务仅在所有子任务完成时完成。但是,这不是默认行为,通常建议您避免选择此行为(例如,将TaskCreationOptions.AttachedToParent
传递到Task.Factory.StartNew
)
如果您确实使用了该行为(请不要),那么您将在第一次调用SubmitTemp()
时看到您的激活循环,并且不再处理任何消息
问题3:奥尔良是否使用同步上下文?
Orleans不使用SynchronizationContext
。相反,它使用自定义TaskScheduler
实现。请参阅。每个激活都有自己的ActivationTaskScheduler
,所有消息都是使用该计划程序的计划程序
关于下面的问题,任务
实例(每个实例代表一个同步工作)根据激活计划的线程被插入到同一队列中,因此允许它们交错,但ActivationTaskScheduler
一次仅由一个线程执行。问题1:所描述的执行流是否准确地表示了正在发生的事情?
你的描述在我看来大致正确,但这里有几点更好:
- 是否存在线程池是一个实现细节
- “轮次”是在激活的
TaskScheduler
上计划的每个同步工作部分
- 因此,每当执行必须返回到
任务调度器时,循环就结束了
- 这可能是因为未同步完成的
await
被命中,或者用户根本没有使用await
,正在使用ContinueWith
或自定义等待项进行编程
- 回合可以从非顶级方法结束,例如,如果代码更改为
等待提交(x)
而不是。忽略()
它,则回合将在任务.Delay(…)
在提交(x)
内命中时结束
问题2:示例程序是否证明违反了单线程保证?
不,在给定时间只有一个线程执行grain的代码。但是,该“线程”必须在激活的TaskScheduler
上调度的各种任务之间分配时间。也就是说,您永远不会暂停进程并发现两个线程正在执行grain的代码同时,
就运行时而言,当任务
(或其他可等待类型)完成时,消息处理结束从顶级方法返回的消息完成。在此之前,不会计划在激活时执行新消息。始终允许从方法生成的后台任务与其他任务交错
.NET允许将子任务附加到其p
Client giving another request
Client Task Status - WaitingForActivation
500 outer received temperature: 23.79668
Internal function getting awaiting task 0
500 outer received temperature: 23.79668 exiting
Internal function getting awaiting task 1
Internal function getting awaiting task 2
Internal function getting awaiting task 3
Internal function getting awaiting task 4
Client giving another request
Client Task Status - WaitingForActivation
500 outer received temperature: 39.0514
Internal function getting awaiting task 0 <------- from second call to SubmitTemp
500 outer received temperature: 39.0514 exiting
Internal function getting awaiting task 5 <------- from first call to SubmitTemp
Internal function getting awaiting task 1
Internal function getting awaiting task 6
Internal function getting awaiting task 2
Internal function getting awaiting task 7
Internal function getting awaiting task 3
Internal function getting awaiting task 8
Internal function getting awaiting task 4
Internal function getting awaiting task 9