C# 无法使用';等待&x27;不止一次
当我只能使用wait一次时,我陷入了一个非常奇怪的境地。请参见下面的示例:C# 无法使用';等待&x27;不止一次,c#,async-await,C#,Async Await,当我只能使用wait一次时,我陷入了一个非常奇怪的境地。请参见下面的示例: private async Task RegisterInstruments(byte clientId, RegisterInstrumentRequest registerInstrumentRequest, bool isPriority = false) { if (registerInstrumentRequest != null && registerInstrumentRequest.R
private async Task RegisterInstruments(byte clientId, RegisterInstrumentRequest registerInstrumentRequest, bool isPriority = false)
{
if (registerInstrumentRequest != null && registerInstrumentRequest.RegisterIntrstuments != null)
{
var r1 = await instrumentManager.GetInstrumentAsync("AMZN");
logger.Debug("reached r1");
var r2 = await instrumentManager.GetInstrumentAsync("AMZN");
logger.Debug("reached r2");
}
}
Serilog输出:
当我启动调试器并逐行执行时,我可以执行直到行var r1=…
,并将预期结果输入r1
,然后我按F10,调试器将刚刚完成,就像我单击“继续”一样,我的winform UI将出现
调用完成后,调试器不会返回代码。GetInstrumentAsync
方法只是使用EntityFramework从数据库中获取记录(下面的代码)。这真的不需要太多时间
此外,它不会在调试部分的输出窗口中打印任何异常内容
我所尝试的:
try/catch
,但它永远不会进入catch
块.Result
调用GetInstrumentAsync
,而不使用wait
。一模一样李>
async/await
),并按预期使用它GetInstrumentAsync
方法的代码:
公共异步任务GetInstrumentAsync(字符串全名)
{
返回等待_dbContext.Instruments
.AsNoTracking()
.SingleOrDefaultAsync(m=>m.FullName==FullName);
}
代码的其余部分(为了简洁起见,删除了一些语句):
publicsocketmanager(框架)
{
socket.ReceiveReady+=SocketServer\u ReceiveReady;
}
//我无法执行此“异步任务”,因为这是一个偶数侦听器。它必须返回void而不是Task。所以我使用了。等等()
私有void SocketServer_ReceiveReady(对象发送方,NetMQSocketEventArgs e)
{
ProcessMessage(例如Socket.ReceiveMultipartMessage()).Wait();
}
专用异步任务ProcessMessage(NetMQMessage netMQFrames,bool isPriority=false)
{
RequestMessageType messageType=(RequestMessageType)netMQFrames[2]。ConvertToInt32();
字节clientId=netMQFrames[0]。缓冲区[0];
字节[]messagBuffer=netMQFrames.FrameCount>3?netMQFrames[3]。缓冲区:null;
开关(消息类型)
{
//为简洁起见,删除了其他案例
案例请求MessageType.RegisterInstruments:
RegisterInstrumentRequest RegisterInstrumentRequest=MessageParser.Deserialize(messagBuffer);
等待RegisterInstruments(客户端ID、registerInstrumentRequest、iPriority);
打破
}
}
后台线程调用GetInstrumentAsync
方法,它使用类的可重用实例(\u dbContext
标识符)。这是一个实体框架类,所以在多线程应用程序中使用它时要小心。要么使用锁同步对单个实例的访问,要么在每个数据库请求上创建一个新实例。奇怪的是,就在这个特殊情况下(NetMQ),我没有得到线程安全异常,而当从多个线程访问\u dbContext
时,我在应用程序中的某些其他位置也遇到了线程安全异常。在这种情况下,我确实创建了一个单独的\u dbContext
实例。不知道为什么EF从来没有因为这个例子而抱怨过这个线程安全问题。可能在这个例子中,_dbContext被多个线程调用,但不是并发调用的。由于某些巧合的原因,请求可能被序列化。如果您不喜欢在每个请求上创建一个新的DbContext
实例,那么可以使用类为每个线程存储一个单独的实例。我不确定这是否是一个好主意。评论不是为了进一步讨论;这段对话已经结束。
reached r1
public async Task<DsInstrument> GetInstrumentAsync(string fullName)
{
return await _dbContext.Instruments
.AsNoTracking()
.SingleOrDefaultAsync(m => m.FullName == fullName);
}
public SocketManager(Framework framework)
{
socket.ReceiveReady += SocketServer_ReceiveReady;
}
// I cannot make this `async Task` as this is an even listener. It must return void not Task. So I am using .Wait()
private void SocketServer_ReceiveReady(object sender, NetMQSocketEventArgs e)
{
ProcessMessage(e.Socket.ReceiveMultipartMessage()).Wait();
}
private async Task ProcessMessage(NetMQMessage netMQFrames, bool isPriority = false)
{
RequestMessageType messageType = (RequestMessageType)netMQFrames[2].ConvertToInt32();
byte clientId = netMQFrames[0].Buffer[0];
byte[] messagBuffer = netMQFrames.FrameCount > 3 ? netMQFrames[3].Buffer : null;
switch (messageType)
{
// Remved other cases for brevity
case RequestMessageType.RegisterInstruments:
RegisterInstrumentRequest registerInstrumentRequest = MessageParser.Deserialize<RegisterInstrumentRequest>(messagBuffer);
await RegisterInstruments(clientId, registerInstrumentRequest, isPriority);
break;
}
}