这两个System.Timers.Timer和System.Threading.Timer火在离请求的那些相当不同的时间间隔.例如:
new System.Timers.Timer(1000d / 20);
Run Code Online (Sandbox Code Playgroud)
产生一个每秒发射16次而不是20次的计时器.
为了确保太长的事件处理程序没有副作用,我写了这个小测试程序:
int[] frequencies = { 5, 10, 15, 20, 30, 50, 75, 100, 200, 500 };
// Test System.Timers.Timer
foreach (int frequency in frequencies)
{
int count = 0;
// Initialize timer
System.Timers.Timer timer = new System.Timers.Timer(1000d / frequency);
timer.Elapsed += delegate { Interlocked.Increment(ref count); };
// Count for 10 seconds
DateTime start = DateTime.Now;
timer.Enabled = true;
while (DateTime.Now < start + TimeSpan.FromSeconds(10))
Thread.Sleep(10);
timer.Enabled = false;
// Calculate …Run Code Online (Sandbox Code Playgroud) 我实现了以下后台处理线程,其中Jobs是Queue<T>:
static void WorkThread()
{
while (working)
{
var job;
lock (Jobs)
{
if (Jobs.Count > 0)
job = Jobs.Dequeue();
}
if (job == null)
{
Thread.Sleep(1);
}
else
{
// [snip]: Process job.
}
}
}
Run Code Online (Sandbox Code Playgroud)
这产生正在进入作业时之间的noticable延迟,当他们实际上开始运行(作业批次在一旦进入,而每个工作只是[比较]小)的延迟是不是一个大问题,但我开始思考这个问题,并做了以下改变:
static ManualResetEvent _workerWait = new ManualResetEvent(false);
// ...
if (job == null)
{
lock (_workerWait)
{
_workerWait.Reset();
}
_workerWait.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)
线程添加作业现在锁定_workerWait并_workerWait.Set()在完成添加作业时调用.这个解决方案(貌似)立即开始处理工作,延迟完全消失.
我的问题部分是"为什么会发生这种情况?",被认为Thread.Sleep(int)可以比你指定的更长时间地睡眠,部分是"如何ManualResetEvent实现这种性能水平?".
编辑:由于有人询问了排队项目的功能,现在它和目前的完整系统一起.
public void RunTriggers(string data)
{
lock …Run Code Online (Sandbox Code Playgroud) 我比较了从数据库表中获取一些相当大的数据的两个查询.对于查询一个我使用Linq To Sql而另一个我通过ADO.NET使用passthrough SQL.
我知道Linq To Sql必须在幕后做很多工作,但实际上它在做什么?这两个查询获取相同数量的数据,但Linq To Sql查询速度慢了5秒以上,并且使用了150多个RAM!
这是我的测试代码:
使用Linq To Sql:
public void MakeList()
{
int start = Environment.TickCount;
var document = from d in _dm.tDokuments select d;
List<tDokument> documentList = document.ToList();
int end = Environment.TickCount;
GridView1.DataSource = documentList;
GridView1.DataBind();
Label1.Text = (end - start).ToString();
}
Run Code Online (Sandbox Code Playgroud)
直通SQL + ADO.NET:
public void MakeList()
{
int start = Environment.TickCount;
SqlCommand sqlCommand = new SqlCommand("SELECT * FROM tDokument", _connection);
SqlDataAdapter da = new SqlDataAdapter(sqlCommand);
DataSet ds = new DataSet();
da.Fill(ds);
int …Run Code Online (Sandbox Code Playgroud) 我有一个线程每40毫秒(25赫兹)生成一个网络数据包,它是一个无限循环(直到被告知停止),我正在使用thread.sleep.
当我构建数据包时,其中一个值是当前的GPS时间,使用DateTime.UtcNow并添加闰秒.
这在我开始时工作正常,但随着时间的推移漂移,大约2小时后,它落后了5秒.
我有一个Symmetrom GPS时间服务器,我正在使用他们的软件作为NTP客户端,它说PC上的累积漂移大约是1.2秒(我注意到的大多数是在PC关闭而不同步时漂移到NTP).
任何人都知道什么是错的?我知道thread.sleep不是完美的计时,而Windows不是RTOS,但漂移没有意义,丢帧会.
由于一些专有和ITAR问题,我无法发布代码,但我可以发布一个粗略的大纲:
while(!abort) {
currentTime = DateTime.UtcNow + leapSeconds ;
buildPacket(currentTime);
stream.Write(msg, 0, sendSize);
//NetworkStream Thread.Sleep(40);
}
Run Code Online (Sandbox Code Playgroud)
我在Windows 7并使用Visual Studios 2010.
继这个问题之后......我正在尝试对以下场景进行单元测试:
我有一个类允许一个方法调用一个方法来执行某些操作,如果它失败等待一秒钟并重新调用该方法.
假设我想调用方法DoSomething()...但是如果DoSomething()抛出异常,我希望能够重试最多调用它3次,但每次尝试之间等待1秒.在这种情况下,单元测试的目的是验证当我们调用DoSomething()3次,每次重试之间等待1秒钟时,总时间> = 3秒.
不幸的是,我能想到测试它的唯一方法是使用秒表来计时....它有两个副作用......
如果有一种方法可以模拟出这种依赖性,那么我的测试能够更快地运行并且在结果中相当一致,那会更好.不幸的是,我想不出办法这么做......所以我想我会问,看看你们中间是否有人遇到过这个问题......
关于C#中的线程,我有一个小问题.出于某种原因,当我打开Chrome时,我的线程从32ms延迟加速到16ms延迟,当我关闭Chrome时它会回到32ms.我正在使用Thread.Sleep(1000 / 60)延迟.有人可以解释为什么会发生这种情况,并建议一个可能的解决方案吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static bool alive;
static Thread thread;
static DateTime last;
static void Main(string[] args)
{
alive = true;
thread = new Thread(new ThreadStart(Loop));
thread.Start();
Console.ReadKey();
}
static void Loop()
{
last = DateTime.Now;
while (alive)
{
DateTime current = DateTime.Now;
TimeSpan span = current - last;
last = current;
Console.WriteLine("{0}ms", span.Milliseconds);
Thread.Sleep(1000 / 60);
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我需要一个函数在+/- 1ms内的精确时间运行.我尝试过以下操作但最终执行时间最短为15毫秒.
void Main()
{
System.Timers.Timer timer = new System.Timers.Timer(1); // executes every 15ms
timer.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
System.Timers.Timer timer2 = new System.Timers.Timer(5); // executes every 15ms
timer2.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
System.Timers.Timer timer2 = new System.Timers.Timer(20); // executes every 31ms
timer3.Elapsed += new System.Timers.ElapsedEventHandler(myFunction);
timer.Start();
timer2.Start();
timer3.Start();
}
void myFunction()
{
doWord();
}
Run Code Online (Sandbox Code Playgroud)
使用Thread.Sleep()获得相同的结果.
申请概要.
我将在一个包含1553条消息的文件中读取(每条消息都有一个时间戳).我需要尽可能接近文件所包含的时间重播这些消息.消息的时间戳记录在microsec中,但我只需要msec准确度.
这是使用DDC 1553卡(PCI卡)完成的.我有一个分析器,它允许我查看消息,包括消息之间的增量时间,以测量我的准确性.
我正在使用的机器有一个具有超线程的QuadCore.使用for(int i = 0; .....)我可以获得0.5毫秒的准确度.然而,这是非常低效的,并且如果可能的话,更愿意使用更现实且更便携的方法.
我没有使用Thread所以不能使用thread.sleep()方法..我的程序的一部分,我需要引入一些延迟..不正是1毫秒但几乎是..
这是已知的标准方法?
请参阅本文底部的代码.它应该在列表框中添加"3",然后在一秒钟后添加"2",然后在一秒钟后添加"1",然后运行程序的主代码.但是,一旦我执行程序,它就会保持3秒钟的空白,然后显示所有的3,2和1,之后所有代码都会直接启动.我想在视觉上看到每个数字都显示一秒延迟.我该怎么做呢?
private void Main()
{
countdown();
//Main Code
}
private void countdown()
{
listBox1.Items.Clear();
listBox1.Items.Add("3");
System.Threading.Thread.Sleep(1000);
listBox1.Items.Add("2");
System.Threading.Thread.Sleep(1000);
listBox1.Items.Add("1");
System.Threading.Thread.Sleep(1000);
listBox1.Items.Clear();
}
Run Code Online (Sandbox Code Playgroud) 因此,我的程序基本上是创建Main的子线程并从用户获得一个整数作为输入,并通过将其计数为1000将该数字转换为milisecond.
但是在for循环中,当我输入数字5作为输入时,Thread.Sleep()会休眠大约10秒.
代码:
static void CallToChildThread()
{
Console.WriteLine("How many seconds do you want this thread to rest?");
int time = Convert.ToInt32(Console.Read());
int mili = time * 1000;
for (int i = 0; i < time; i++)
{
Console.Write(". ");
Thread.Sleep(mili);
}
Console.WriteLine();
}
Run Code Online (Sandbox Code Playgroud)
因此,当我键入5时,代码将乘以5乘以1000并将5000存储在mili中.
但是,在for循环中,当执行Thread.Sleep(mili)时,它不会整整睡5秒,它会在循环中迭代一次后休眠10秒.
此外,当我用5000更改替换mili以使线程休眠5秒时,每次循环,并且它工作,但循环迭代超过我的预期.例如,这是我输入的输入:
How many seconds do you want this thread to rest?
5
. . . . . . . . . .
Run Code Online (Sandbox Code Playgroud)
每次迭代时它都会正常计算5秒.但它迭代超过5.如果我键入5然后不应该for循环迭代5次并中止?只显示5个时期?
c# ×8
.net ×3
sleep ×2
timer ×2
behavior ×1
data-binding ×1
deviation ×1
frequency ×1
linq-to-sql ×1
mocking ×1
performance ×1
sql ×1
thread-sleep ×1
time ×1
timing ×1
unit-testing ×1
wait ×1