繁体   English   中英

有没有办法重用同一个线程?

[英]Is there a way to reuse the same thread?

var a = 3
var b= 5
for (int i = 0; i < 10; i++)
{
    var c = a + b;
    Console.WriteLine(c); //This line should execute on another thread
}

我怎样才能在另一个线程上打印 c 的值,而无需每次迭代都创建一个新线程? 我想让它在另一个线程上运行的原因是因为写入 c 的值会阻塞线程并使脚本变慢。 基本上它用于视觉反馈

注意:我不能在线程中放置一个循环,因为线程应该只在计算 c 之后运行

我认为您需要一个标准的发布者/消费者方法。

using System.Threading.Channels;

Channel<int> channel = Channel.CreateUnbounded<int>();
ChannelWriter<int> writer = channel.Writer;
ChannelReader<int> reader = channel.Reader;

var task = Task.Run(async () => await Consume());

var a = 3;
var b = 5;
for (int i = 0; i < 10; i++)
{
    var c = a + b + i;
    await writer.WriteAsync(c);
}
writer.Complete();

await task; // or Console.ReadKey();

async Task Consume()
{
    await foreach (int x in reader.ReadAllAsync())
    {
        Console.WriteLine(x);
    }
}

如有必要,将数据发布到通道的代码部分也可以在单独的线程中执行。

根据您提供的信息,可能的解决方案如下:

int sum = 0;
object lockObj = new object();

var tokenSource2 = new CancellationTokenSource(); 
CancellationToken ct = tokenSource2.Token;

void Progress()
{
    while (true)
    {
        // We should lock only if writting to the sum var but this is just an example.
        lock (lockObj)
        {
            Console.WriteLine(sum);
        }
        // Just simple wait in order to not write constantly to the console.
        Thread.Sleep(100);
        // If process canceled (finished), then exit.
        if (ct.IsCancellationRequested)
            return;
    }
}

var a = 3;
var b = 5;

Task? t = null;
for (int i = 0; i < 100000; i++)
{
    // Lock to be sure that there is no concurrency issue with the Progress method if it writes to the variable.
    // In our case it shouldn't be required as it only reads.
    lock (lockObj)
    {
        sum = a + b;
    }
    if (t == null)
        t = Task.Run(() => Progress());
}
tokenSource2.Cancel();

t.Wait();

注意事项:

  1. 我们锁定了sum变量的访问,尽管它不是必需的,因为我们只是从中读取。 如果您不打算从后台线程写入锁定语句,则可以安全地删除它。
  2. 我们使用取消标记来指示执行计算的线程(在我们的例子中是主线程)的终止。 这样,另一个线程将正确终止,并且不会最终运行无限循环。
  3. 结束计算后,我们使用 Task.Wait()。 如果我们不这样做,控制台应用程序将立即终止后台线程,我们可能无法在屏幕上显示结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM