我是新到的;我主要做的是 Java。
我想按照以下方针执行一个时间表:
int now= Time.now();
while(true)
{
tryMethod();
if(now > now+5000) throw new TimeoutException();
}
我如何在C#中落实这一点? 感谢!
我是新到的;我主要做的是 Java。
我想按照以下方针执行一个时间表:
int now= Time.now();
while(true)
{
tryMethod();
if(now > now+5000) throw new TimeoutException();
}
我如何在C#中落实这一点? 感谢!
一种可能的办法是:
Stopwatch sw = new Stopwatch();
sw.Start();
while(true)
{
tryMethod();
if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}
然而,你目前无法打破你的 lo。 我建议添加<条码>、标准/编码>,并改写如下:
Stopwatch sw = new Stopwatch();
sw.Start();
while(!tryMethod())
{
if(sw.ElapsedMilliseconds > 5000) throw new TimeoutException();
}
问题很老,但又是另一种选择。
using(CancellationTokenSource cts = new CancellationTokenSource(5000))
{
cts.Token.Register(() => { throw new TimeoutException(); });
while(!cts.IsCancellationRequested)
{
tryMethod();
}
}
在技术上,你还应宣传<代码> Token in the tryMethod(
to interupt it graceally.
Working demo: (note I had tomov the exceptionhanging conduct as .netfiddle don .)
我认为,你可以与一位时间和代表一道这样做,我的榜样守则如下:
using System;
using System.Timers;
class Program
{
public delegate void tm();
static void Main(string[] args)
{
var t = new tm(tryMethod);
var timer = new Timer();
timer.Interval = 5000;
timer.Start();
timer.Elapsed += (sender, e) => timer_Elapsed(t);
t.BeginInvoke(null, null);
}
static void timer_Elapsed(tm p)
{
p.EndInvoke(null);
throw new TimeoutException();
}
static void tryMethod()
{
Console.WriteLine("FooBar");
}
}
您尝试了Method,然后你创建了一名代表,并在Method上指出这位代表,然后,你开始担任这一代表。 然后,你有时间,间隔时间为5000米,你将你的代表转往你的时间过长的方法(代表应是一个参考类型,而不是一个价值类别),一旦5 000秒已经过去,你就把Envoke方法称作代表。
只要试图解决问题,就应该做你想要做的事情:
• 移动时节省日光时间或改变时区的安全:
DateTime startTime = DateTime.Now;
while(true)
{
tryMethod();
if(DateTime.Now.Subtract(startTime).TotalMilliseconds > 5000)
throw new TimeoutException();
}
时区和日光节省时间
DateTime startTime = DateTime.UtcNow;
while(true)
{
tryMethod();
if(DateTime.UtcNow.Subtract(startTime).TotalMilliseconds > 5000)
throw new TimeoutException();
}
(www.net 3.5或更高, 日期:Offset)
DateTimeOffset startTime = DateTimeOffset.Now;
while(true)
{
tryMethod();
if(DateTimeOffset.Now.Subtract(startTime).TotalMilliseconds > 5000)
throw new TimeoutException();
}
在此,我采用一种方法,总结出时间的任务。
public class TaskWithTimeoutWrapper
{
protected volatile bool taskFinished = false;
public async Task<T> RunWithCustomTimeoutAsync<T>(int millisecondsToTimeout, Func<Task<T>> taskFunc, CancellationTokenSource cancellationTokenSource = null)
{
this.taskFinished = false;
var results = await Task.WhenAll<T>(new List<Task<T>>
{
this.RunTaskFuncWrappedAsync<T>(taskFunc),
this.DelayToTimeoutAsync<T>(millisecondsToTimeout, cancellationTokenSource)
});
return results[0];
}
public async Task RunWithCustomTimeoutAsync(int millisecondsToTimeout, Func<Task> taskFunc, CancellationTokenSource cancellationTokenSource = null)
{
this.taskFinished = false;
await Task.WhenAll(new List<Task>
{
this.RunTaskFuncWrappedAsync(taskFunc),
this.DelayToTimeoutAsync(millisecondsToTimeout, cancellationTokenSource)
});
}
protected async Task DelayToTimeoutAsync(int millisecondsToTimeout, CancellationTokenSource cancellationTokenSource)
{
await Task.Delay(millisecondsToTimeout);
this.ActionOnTimeout(cancellationTokenSource);
}
protected async Task<T> DelayToTimeoutAsync<T>(int millisecondsToTimeout, CancellationTokenSource cancellationTokenSource)
{
await this.DelayToTimeoutAsync(millisecondsToTimeout, cancellationTokenSource);
return default(T);
}
protected virtual void ActionOnTimeout(CancellationTokenSource cancellationTokenSource)
{
if (!this.taskFinished)
{
cancellationTokenSource?.Cancel();
throw new NoInternetException();
}
}
protected async Task RunTaskFuncWrappedAsync(Func<Task> taskFunc)
{
await taskFunc.Invoke();
this.taskFinished = true;
}
protected async Task<T> RunTaskFuncWrappedAsync<T>(Func<Task<T>> taskFunc)
{
var result = await taskFunc.Invoke();
this.taskFinished = true;
return result;
}
}
然后,你可以这样说:
await new TaskWithTimeoutWrapper().RunWithCustomTimeoutAsync(10000, () => this.MyTask());
或
var myResult = await new TaskWithTimeoutWrapper().RunWithCustomTimeoutAsync(10000, () => this.MyTaskThatReturnsMyResult());
如果你想要取消当成不变的任务,那么你可以增加取消。
希望会有助于
另一种方式是:
public class TimeoutAction
{
private Thread ActionThread { get; set; }
private Thread TimeoutThread { get; set; }
private AutoResetEvent ThreadSynchronizer { get; set; }
private bool _success;
private bool _timout;
/// <summary>
///
/// </summary>
/// <param name="waitLimit">in ms</param>
/// <param name="action">delegate action</param>
public TimeoutAction(int waitLimit, Action action)
{
ThreadSynchronizer = new AutoResetEvent(false);
ActionThread = new Thread(new ThreadStart(delegate
{
action.Invoke();
if (_timout) return;
_timout = true;
_success = true;
ThreadSynchronizer.Set();
}));
TimeoutThread = new Thread(new ThreadStart(delegate
{
Thread.Sleep(waitLimit);
if (_success) return;
_timout = true;
_success = false;
ThreadSynchronizer.Set();
}));
}
/// <summary>
/// If the action takes longer than the wait limit, this will throw a TimeoutException
/// </summary>
public void Start()
{
ActionThread.Start();
TimeoutThread.Start();
ThreadSynchronizer.WaitOne();
if (!_success)
{
throw new TimeoutException();
}
ThreadSynchronizer.Close();
}
}
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(10000);
try
{
Task task = Task.Run(() => { methodToTimeoutAfter10Seconds(); }, cts.Token);
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
using (cts.Token.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
{
if (task != await Task.WhenAny(task, tcs.Task))
{
throw new OperationCanceledException(cts.Token);
}
}
/* Wait until the task is finish or timeout. */
task.Wait();
/* Rest of the code goes here */
}
catch (TaskCanceledException)
{
Console.WriteLine("Timeout");
}
catch (OperationCanceledException)
{
Console.WriteLine("Timeout");
}
catch (Exception ex)
{
Console.WriteLine("Other exceptions");
}
finally
{
cts.Dispose();
}
利用成熟的图书馆Polly,可采用乐观方式(Sus Cancellation Token)实施:
AsyncTimeoutPolicy policy = Policy.TimeoutAsync(60, TimeoutStrategy.Optimistic);
await policy.ExecuteAsync(async cancel => await myTask(cancel), CancellationToken.None);
www.un.org/spanish/ga/president Token, Task> e.gasync Task MyTast (Cancellation) <>/代码>
What is the use of default keyword in C#? Is it introduced in C# 3.0 ?
I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...
I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...
I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...
I have two EF entities. One has a property called HouseNumber. The other has two properties, one called StartHouseNumber and one called EndHouseNumber. I want to create a many to many association ...
How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...
Since I cannot order my dictionary, what is the best way of going about taking key value pairs and also maintaing an index?
Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...