multithreading - 将 Task.Run 中的代码编组到调用线程
问题描述
我正在使用Task.Run
. 我将它存储Task
在服务器类中的一个字段中,以便将来如果需要可以取消它。一旦Task
启动,我就会启动一个同步运行状态的游戏引擎。
private void ListenForConnection()
{
this.listeningTokenSource = new CancellationTokenSource();
this.listeningTask = Task.Run(async () =>
{
while (!this.IsDeleted)
{
Socket clientSocket = await this.serverSocket.AcceptAsync();
await this.CreatePlayerConnection(clientSocket);
}
}, this.listeningTokenSource.Token);
}
private async Task CreatePlayerConnection(Socket clientConnection)
{
IServerConnection playerConnection = await this.connectionFactory.CreateConnection(clientConnection);
IPlayer player = await this.playerFactory.CreatePlayer(playerConnection);
if (playerConnection is TcpConnection tcpConnection)
{
tcpConnection.SetPlayer(player);
}
this.connectedPlayers.Add(player);
await this.PlayerConnected(player);
await player.ExecuteCommand(this.InitialCommand);
}
在这种情况下,如果玩家连接到服务器,我将 Socket 传递给一个IServerConnection
实例并将其分配给玩家。当客户端命令通过套接字发送时,IServerConnection
该客户端接收到它会解析它,然后在管道中的某个地方它会想要在此之外修改游戏状态IServerConnection
;通过与引擎内运行的实体进行交互(甚至可能在另一个线程本身上)。
这一切都发生在netcoreapp2.0
控制台应用程序中。
当客户端套接字进入不同线程中的触摸状态时,我会遇到源自后台操作的客户端套接字问题吗?在 WPF 和 aspnet 中,我过去使用过 SynchronizationContext,但控制台应用程序没有这个。
什么是一种干净的方法来确保我不会到处死锁,而不必到处乱扔锁。我可以在启动ListenForConnection()
任务之前捕获当前线程并将状态更改回原始线程吗?
解决方案
从我的角度来看,您总是会得到一个公共资源,该资源将由不同的线程更新。所以使用 alock
是可行的方法。但是,如果您将资源和锁包装在一个对象中,您可以将所有synchronization
操作保存在本地。
public class Resource{
public int Value{get;set;}
}
public class Engine
{
private Resource commonResource=new Resource();
private object @lock=new object();
public void ChangeResource(int newvalue)
{
lock(@lock)
{
this.commonResource.Value=newvalue;
}
}
}
public class Client{
private Engine engine;
public Client(Engine engine)
{
this.engine=engine;
}
public void ChangeResource(int newValue){
this.engine.ChangeResource(newvalue);
}
}
PS我不知道你如何使用你的引擎/包装器(无论你说客户端进行更改是什么)所以我只是将它注入所有客户端。你也可以使用singleton
。如果您运行async
操作,请考虑使用SempahoreSlim而不是锁。
推荐阅读
- git - 需要一个本地分支以在 git 中获取其他代码
- java - Flutter如何自动从页面导航到另一个页面
- javascript - 如何在没有捆绑器的情况下在 Nw.js 项目中使用 Vue.js?
- ios - 无法在 Xcode Objective-c 中将按钮连接到 wkwebview
- c - 使用 NULL 指针初始化数组并引发 GCC 抛出错误
- amazon-web-services - Lambda 中对 ApiGateway 的请求导致无法满足请求
- javascript - iFrame 变为空
- java - 如何使用 OjAlgo 在 OperateOnAll 上使用 abs、sqrt 等?
- java - 在另一个 Activity 中使用 RecyclerViewAdapter 的 ArrayList
- javascript - 使用方法作为过滤器的回调函数会影响回调的范围