首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Console.ReadKey()不工作

Console.ReadKey()不工作
EN

Stack Overflow用户
提问于 2015-07-17 07:11:35
回答 1查看 4.1K关注 0票数 5

请看original Microsoft example

在第二个示例中,我们发现以下代码:

代码语言:javascript
复制
// The simplest UI thread ever invented.
Task.Run(() =>
{
    if (Console.ReadKey().KeyChar == 'c')
        cts.Cancel();
});

(运行以下代码所需的完整代码:)

代码语言:javascript
复制
static int inputs = 2000;
static void Main(string[] args)
{
    // The token source for issuing the cancelation request.
    CancellationTokenSource cts = new CancellationTokenSource();

    // A blocking collection that can hold no more than 100 items at a time.
    BlockingCollection<int> numberCollection = new BlockingCollection<int>(100);

    // Set console buffer to hold our prodigious output.
    //Console.SetBufferSize(80, 2000);

    // The simplest UI thread ever invented.
    Task.Run(() =>
    {
        if (Console.ReadKey().KeyChar == 'c')
            cts.Cancel();
        else
        {
            Debugger.Break();
        }
    });

    // Start one producer and one consumer.
    Task.Run(() => NonBlockingConsumer(numberCollection, cts.Token));
    Task.Run(() => NonBlockingProducer(numberCollection, cts.Token));

    Console.WriteLine("Press the Enter key to exit.");
    Console.ReadLine();
}

static void NonBlockingConsumer(BlockingCollection<int> bc, CancellationToken ct)
{
    // IsCompleted == (IsAddingCompleted && Count == 0)
    while (!bc.IsCompleted)
    {
        int nextItem = 0;
        try
        {
            if (!bc.TryTake(out nextItem, 0, ct))
            {
                Console.WriteLine(" Take Blocked");
            }
            else
                Console.WriteLine(" Take:{0}", nextItem);
        }

        catch (OperationCanceledException)
        {
            Console.WriteLine("Taking canceled.");
            break;
        }

        // Slow down consumer just a little to cause
        // collection to fill up faster, and lead to "AddBlocked"
        Thread.SpinWait(500000);
    }

    Console.WriteLine("\r\nNo more items to take. Press the Enter key to exit.");
}

static void NonBlockingProducer(BlockingCollection<int> bc, CancellationToken ct)
{
    int itemToAdd = 0;
    bool success = false;

    do
    {
        // Cancellation causes OCE. We know how to handle it.
        try
        {
            // A shorter timeout causes more failures.
            success = bc.TryAdd(itemToAdd, 2, ct);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Add loop canceled.");
            // Let other threads know we're done in case
            // they aren't monitoring the cancellation token.
            bc.CompleteAdding();
            break;
        }

        if (success)
        {
            Console.WriteLine(" Add:{0}", itemToAdd);
            itemToAdd++;
        }
        else
        {
            Console.Write(" AddBlocked:{0} Count = {1}", itemToAdd.ToString(), bc.Count);
            // Don't increment nextItem. Try again on next iteration.

            //Do something else useful instead.
            UpdateProgress(itemToAdd);
        }

    } while (itemToAdd < inputs);

    // No lock required here because only one producer.
    bc.CompleteAdding();
}

static void UpdateProgress(int i)
{
    double percent = ((double)i / inputs) * 100;
    Console.WriteLine("Percent complete: {0}", percent);
}

该代码应该做什么是完全清楚的:它应该打破按下c,但它不工作。相反,它一直运行到最后,要求使用Enter关闭。

我们怎么才能解决这个问题?

这似乎是一个线程问题,但它是一个.net4.5的演示,代码不起作用。

'c‘的KeyPress不设置CancelationToken。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-17 07:20:34

你完全正确的例子是错误的。只是坏了。

它不能工作的原因是它不等待Task的完成,而是等待Console.ReadLine的完成。这将解决以下问题:

取代:

代码语言:javascript
复制
Task.Run(() => NonBlockingConsumer(numberCollection, cts.Token));
Task.Run(() => NonBlockingProducer(numberCollection, cts.Token));

通过以下方式:

代码语言:javascript
复制
Task t1 = Task.Run(() => NonBlockingConsumer(numberCollection, cts.Token));
Task t2 = Task.Run(() => NonBlockingProducer(numberCollection, cts.Token));

Task.WaitAll(t1, t2);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31470247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档