如何在特定时间后停止执行方法? [英] How to stop the execution of a method after a specific time?

查看:129
本文介绍了如何在特定时间后停止执行方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在有限的时间内未完成方法,我需要停止执行该方法。

I need to stop the execution of a method if it has not completed within a limited period of time.

要执行此工作,我可以使用 Thread.Abort 方法:

To do this work I can use the Thread.Abort method in this way:

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,是否有更好的方法?

Given that I'm using .NET 3.5, is there a better way?

编辑:在此处按照我的 entryPoint 的注释进行操作,但我正在为任何 entryPoint

following the comments here my entryPoint, but I'm looking for a good way for any entryPoint.

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


推荐答案

答案取决于工作'。如果可以安全地停止工作(即不执行某些I / O阻止操作),请使用 Backgroundworker.CancelAsync(...)

Answer depends on 'the work'. If work is something that can be safely stopped (i.e. not some I/O blocking operation) - use Backgroundworker.CancelAsync(...)

如果您必须努力工作-我会考虑使用程序,在这种情况下,正在中止进程更干净-并且 process.WaitForExit(timeout)是您的朋友。

If you do have to cut hard - I'd consider using a Process, in which case the Aborting process is cleaner - and process.WaitForExit(timeout) is your friend.

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

Suggested TPL is great but unfortunately does not exist in .Net 3.5.

编辑:您可以使用反应式扩展以遵循Jan de Vaan的建议。

You can use Reactive Extensions to follow Jan de Vaan's suggestion.

这是我的动作超时片段-主要是在这里供其他人评论:

Here is my 'action timeout' snip - it's mainly here for others to comment on:

    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想要。这是我设计可取消套接字接收器的尝试:

EDIT: Apparently this isn't exactly what OP wanted. Here's my attempt to devise a 'cancelable' socket receiver:

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;
    }
}

这篇关于如何在特定时间后停止执行方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆