如果一个方法在限定时间内没有完成,我需要停止执行。
要完成这项工作,我可以这样使用 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/