答えは「作品」によって異なります。作業が安全に停止できるものである場合 (つまり、I/O ブロッキング操作ではない場合) - を使用します。Backgroundworker.CancelAsync(...)
あなたが一生懸命カットしなければならない場合 - 私は を使用することを検討します.Process
その場合、Aborting
プロセスはよりクリーンです - そしてprocess.WaitForExit(timeout)
あなたの友達です.
推奨される 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;
}
}