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