【问题标题】:BeginWaitForConnection and Generic.List concurrencyBeginWaitForConnection 和 Generic.List 并发
【发布时间】:2016-08-20 20:25:34
【问题描述】:

我正在使用NamedPipeServerStreamBeginWaitForConnection,每个连接到流的客户端都会调用它们。它采用的回调操作共享静态List。 我想知道BeginWaitForConnection 是异步的并且可能并行运行多个回调这一事实是否会引发List 的并发问题。我已经尝试运行它几次,它似乎工作正常,但我不确定它是否是线程安全的。我应该改用ConcurrentBag,还是在FetchFile 代码周围使用lock(files) {...}?我对异步概念和多线程并不陌生,但并发对我来说相当新,因此非常感谢这里的任何见解。

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();
}

【问题讨论】:

    标签: c# asynchronous concurrency


    【解决方案1】:

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

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

    【讨论】:

    • 那么我应该如何保护共享状态呢? BeginWaitForConnection 不是已经抽象了异步吗?除非您建议我切换到同步版本并自己处理异步?我真的不跟。目前这只是一个准系统的可行性研究,所以不太关心资源,但很好的收获。
    • 您可以有两个并发的 FetchFile 调用,因此 FetchFile 触及的任何资源都必须以安全的方式访问。锁在这里似乎很好。
    • 使用同步版本更好,因为代码变得更简单,而且看起来你不会处理几十个并发连接。但是您需要在新的任务/线程上启动每个连接,因此这不会让您免于并发问题。
    • 锁定它。干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多