2016-08-20 57 views
1

我使用NamedPipeServerStreamBeginWaitForConnection,每连接到流的客户端都会调用NamedPipeServerStreamBeginWaitForConnection。所需的回调操作共享静态List。 我想知道如果BeginWaitForConnection是异步的,并且可能并行运行多个回调将引起List的并发问题。我尝试了几次运行它,它似乎工作正常,但我不确定它是否线程安全。我应该使用ConcurrentBag代替,还是使用lock(files) {...}围绕我的FetchFile代码?我对异步概念和多线程并不陌生,但并发性对我来说是相当新的,所以对此的任何洞察都非常感谢。BeginWaitForConnection和Generic.List并发性

PipeListener是这里的切入点。

static List<string> files = new List<string>(); 

static void PipeListener() 
{ 
    NamedPipeServerStream server = new NamedPipeServerStream("MyPipe", PipeDirection.In, -1, 
            PipeTransmissionMode.Byte, PipeOptions.Asynchronous); 
    server.BeginWaitForConnection(FetchFile, server); 
} 

static void FetchFile(IAsyncResult ar) 
{ 
    PipeListener(); 
    NamedPipeServerStream server = ar.AsyncState as NamedPipeServerStream; 
    server.EndWaitForConnection(ar); 
    StreamReader reader = new StreamReader(server); 
    while (!reader.EndOfStream) 
     files.Add(reader.ReadLine()); 
    server.Dispose(); 
} 

回答

0

在回调BeginWaitForConnection你已经开始新的BeginWaitForConnection电话。这意味着并发调用是可能的,您需要保护共享状态。

请注意,您可能应该使用await而不是过时的APM。另外不要忘记用using来管理您的资源。

+0

那么我应该如何保护共享状态呢?而不是'BeginWaitForConnection'已经抽象了异步?除非你建议我切换到同步版本并自己处理异步?我并不真正关注。这只是一个现在的准系统可行性研究,所以不要太在意资源,但是很好的捕获。 –

+0

您可以有两个并发的FetchFile调用,因此必须以安全的方式访问FetchFile触及的任何资源。锁在这里似乎很好。 – usr

+0

使用同步版本甚至更好,因为代码变得更简单,并且看起来您不会处理几十个并发连接。但是您需要在新的任务/线程上启动每个连接,这样不会使您免受并发问题的困扰。 – usr