相关疑难解决方法(0)

在请求取消之前永远不会结束的任务

我需要一个永远不会结束的任务,直到请求取消.目前最简单的方法是:

var cancellation = new CancellationTokenSource();

var task = Task.Factory.StartNew(async () =>
{
    while (true)
    {
        await Task.Delay(10000, cancellation.Token);
    }
}, cancellation.Token).Unwrap();
Run Code Online (Sandbox Code Playgroud)

我不喜欢的是对Task.Delay方法的调用,因为它需要有限的等待时间间隔.

有更优雅的解决方案吗?

.net asynchronous task-parallel-library

8
推荐指数
2
解决办法
1105
查看次数

设置CancellationToken时抛出任意异常是不好的做法吗?

它是不好的做法,有我的图书馆摆脱抛出不是其他的东西方法OperationCancelledExceptionCancellationToken.IsCancelRequested检测到?

例如:

async Task<TcpClient> ConnectAsync(string host, int port, CancellationToken ct)
{
    var client = new TcpClient();
    try
    {
        using (ct.Register(client.Close, true))
        {
            await client.ConnectAsync(host, port);
        }

        // Pick up strugglers here because ct.Register() may have hosed our client
        ct.ThrowIfCancellationRequested();
    }
    catch (Exception)
    {
        client.Close();
        throw;
    }

    return client;
}
Run Code Online (Sandbox Code Playgroud)

取消后,这有可能抛出ObjectDisposedExceptionNullReferenceException取决于时间.(因为TcpClient.ConnectAsync()TcpClient.Close()同时调用时可以抛出任何一个.)

现在,我可以解决这个问题:

async Task<TcpClient> ConnectAsync(string host, int port, CancellationToken ct)
{
    var client = new TcpClient();
    try …
Run Code Online (Sandbox Code Playgroud)

c# async-await

5
推荐指数
1
解决办法
379
查看次数

try/catch块中的C#未处理异常,检测到冻结

目标:对未经测试的外部代码执行超时.如果我的应用程序会导致另一方冻结,我想立即知道.让我们说这是非常复杂的单元测试.如果测试客户端使用我的应用程序并在500毫秒内返回 - 它已通过,如果没有 - 它失败了.

所以,是的,我不会对客户端温和,这是一个崩溃测试网站.我等了500ms,然后我不在乎客户端等待什么,我想立即将它与异常崩溃,但那么报告它作为测试结果.

可能是许多测试结果之一.

那么,现在,这里,代码:

    Console.Write("Testing");
    try {
        for (int j = 0; j < 3; j++) {
            Console.Write(".");
            for (int i = 0; i < 256; i++) {
                using (var cts = new CancellationTokenSource(500)) {
                    var token = cts.Token;
                    token.Register(() => throw new TimeoutException("FREEZE DETECTED"));
                    clients.Add(LDSCheckAsync().Result);
                }
            }
            clients.ForEach(i => i.Dispose());
            clients.Clear();
        }
        Console.WriteLine("OK.");
    }
    catch {
        clients.ForEach(i => i?.Dispose());
        Console.WriteLine("FAIL!");
    }
Run Code Online (Sandbox Code Playgroud)

我设计的测试失败了.但我没有得到"失败"的消息,我得到了UNHANDLED EXCEPTION.

为什么,以及如何正确地做到这一点.在你尝试写评论之前,请真的考虑我不能IfCancellationRequested在这里使用或类似的东西.测试下的功能通常会立即退出,但由于某些网络错误,它可以进入30秒冻结.当它发生时我完全不知道,为什么更为未知.我做的测试应该帮助我诊断它.冻结不能取消.我知道.我想要的是将冻结转换为一个很好的捕获异常,然后捕获它,然后记录它.但是当try/ catch没有按预期工作时(是的,甚至在VS之外),我很无奈.

既然回答了......

我做了一个方便的工具,以便下次我需要测试冻结代码时让我的生活变得更轻松:

using System.Threading;
using …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing

3
推荐指数
1
解决办法
463
查看次数