【问题标题】:Is it viable to use await/async and threads simultaneously on one method?在一种方法上同时使用等待/异步和线程是否可行?
【发布时间】:2018-02-05 13:16:39
【问题描述】:

我是多线程新手,我有一个(可能)关于同时使用线程和等待/异步的简单问题。我有一个方法可以读取 TCP 流,然后处理它收到的响应。它的调用方式如下所示:

ThreadStart ts = new ThreadStart(ReadTCP);
Thread tt = new Thread(ts);

从流中异步读取数据是否可行?就像在这段代码中一样:

    private async void ReadTCP()
    {
        string responseData = string.Empty;  

        if(streamTCP.DataAvailable) 
        {
            responseData = await  readerTCP.ReadToEndAsync();

            // some code handling the response
        }
    }

使用MarioDS's help编辑的代码

【问题讨论】:

  • 我不认为你的 streamTCP 是线程安全的。此代码会以某种方式失败。
  • 我还没锁,但我知道怎么做。
  • 锁定可能会使您尝试执行的任何线程无效。
  • 这是关于异步 I/O 的。你不需要线程。你不想要线程。你当然不应该使用async void 方法。

标签: c# .net multithreading stream


【解决方案1】:

手动创建和操作线程是一种高级多线程技术,需要开发人员真正知道他在做什么(因为内存隔离、线程之间的同步和编组都是非常高级的主题,而且很容易搞砸了)。线程安全很难。

如果您只想提高应用程序的响应能力,那么几年前添加到 .NET 中的 async 和 await 构造是完美的。它们不一定与多线程相关,因为它是决定是否创建新线程的底层机制(并非总是如此)。

您正在做的是创建一个线程并在该线程上运行ReadTCP 方法。

您可以轻松修复ReadTCP,使其返回Taskasync void 是非常糟糕的做法!)然后像这样使用它:var response = await ReadTCP();async 方法中,它会给你什么你想要的。

要在运行ReadTCP 的同时并行运行某些内容,请为任务创建一个变量,稍后再创建await

var readTask = ReadTCP();
DoOtherStuff();
AndMoreStuff();
AllAtOnce();
var response = await readTask;
DoSomethingWith(response);

顺便说一句,您不必将异步方法包装在 Task.Run 中。而不是做:Task.Run(() => FPXreaderTCP.ReadToEndAsync());,只做await FPXreaderTCP.ReadToEndAsync()

【讨论】:

  • 我不需要在方法完成后将响应存储在任何地方。它用它做一些事情,比如写入数据库——这部分已经是多线程安全的。
  • @FilipS 仍然,让它返回Task(简单来说,异步等效于void)和await它在代码中的适当位置。
猜你喜欢
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多