c# - 如何在特定时间后停止执行方法?

标签 c# c#-3.0

如果一个方法在限定时间内没有完成,我需要停止执行。

要完成这项工作,我可以这样使用 Thread.Abort 方法:

void RunWithTimeout(ThreadStart entryPoint, int timeout)
{
    var thread = new Thread(() =>
    {
        try
        {
            entryPoint();
        }
        catch (ThreadAbortException)
        {   }

    }) { IsBackground = true };

    thread.Start();

    if (!thread.Join(timeout))
        thread.Abort();
}

鉴于我使用的是 .NET 3.5,是否有更好的方法?

编辑:按照我的entryPoint 的评论,但我正在寻找任何entryPoint 的好方法。

void entryPoint()
{
   // I can't use ReceiveTimeout property
   // there is not a ReceiveTimeout for the Compact Framework
   socket.Receive(...);
}

最佳答案

答案取决于“作品”。如果工作是可以安全停止的(即不是某些 I/O 阻塞操作)- 使用 Backgroundworker.CancelAsync(...)

如果您确实必须努力削减 - 我会考虑使用 Process,在这种情况下 Aborting 过程更干净 - 和 process.WaitForExit( timeout) 是你的 friend 。

建议的 TPL 很棒,但遗憾的是在 .Net 3.5 中不存在。

编辑:您可以使用 Reactive Extensions遵循 Jan de Vaan 的建议。

这是我的“操作超时”片段 - 它主要供其他人评论:

    public static bool WaitforExit(this Action act, int timeout)
    {
        var cts = new CancellationTokenSource();
        var task = Task.Factory.StartNew(act, cts.Token);
        if (Task.WaitAny(new[] { task }, TimeSpan.FromMilliseconds(timeout)) < 0)
        { // timeout
            cts.Cancel();
            return false;
        }
        else if (task.Exception != null)
        { // exception
            cts.Cancel();
            throw task.Exception;
        }
        return true;
    }

编辑:显然这不是 OP 想要的。这是我设计“可取消”套接字接收器的尝试:

public static class Ext
{
    public static object RunWithTimeout<T>(Func<T,object> act, int timeout, T obj) where T : IDisposable
    {
        object result = null;
        Thread thread = new Thread(() => { 
            try { result = act(obj); }
            catch {}    // this is where we end after timeout...
        });

        thread.Start();
        if (!thread.Join(timeout))
        {
            obj.Dispose();
            thread.Join();
        }
        return result;
    }       
}

class Test
{
    public void SocketTimeout(int timeout)
    {
        using (var sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
        {
            Object res = Ext.RunWithTimeout(EntryPoint, timeout, sock);
        }
    }

    private object EntryPoint(Socket sock)
    {
        var buf = new byte[256];
        sock.Receive(buf);
        return buf;
    }
}

关于c# - 如何在特定时间后停止执行方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13279362/

相关文章:

c# - 试图将整数和十进制asp.net C#分开

c# - 在 List<T>.ForEach ForEach 方法中更改元素值

c# - 如何将此 XPath 查询转换为 LINQ to XML?

c# - mvc 中创建表单的默认值

c# - 如何提高有关 Trim() 的 Linq 查询性能

c# - 无法使用 linq 更新

c# - 在需要时从接口(interface)转换为某个具体类是一种好习惯吗?

c# - 重构 LINQ 查询

c# - 如何合并两个或多个实现相同接口(interface)的列表

c#-3.0 - 哈希表的XML序列化(C#3.0)