C#将数据传递给Timer

时间:2015-07-29 03:12:49

标签: c# .net timer event-handling

这个问题可能与How do you add a timer to a C# console application重复,但很少有其他类似的问题,但无法找到我想要的答案。

问题:如何将数据从计时器Elapsed事件(System.Timers.Timer)传递给创建计时器的线程(该线程可能不是{ {1}}线程但由Main生成的另一个线程?)

我认为可能有一些微不足道的方法来达到这个目的。就像在创建工作者的线程中调用Main BackgroundWorker事件一样,但无法在MSDN文档或SO中找到方法。我见过的大多数示例都在计时器线程(https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx)中执行了一些操作,但是没有将任何内容传递给原始线程。毋庸置疑,我对C#/ .NET很陌生,所以我们非常感谢解决方案+引用指针。

修改:我不想使用ProgressChanged / Invoke()模式(参见How to use safe threading for a timer(Change timer properties from different thread)),因为这不适用于表单应用。我很想通过创建一个InvokeRequired来解决这个问题,BackgroundWorker每隔一段时间向原始线程报告一次(DoWork将只是循环中的sleep()但是认为.NET可能有这已经是问题了。

3 个答案:

答案 0 :(得分:0)

您会考虑使用dispatcher吗? (虽然你也需要调用一些方法)

当某个线程(可能不是主线程)创建您提到的计时器时,您也可以使用相同的线程创建调度程序。之后,dispatcher.invoke()将让原始线程为您执行这些任务。有关详细信息,请参阅MSDN。

答案 1 :(得分:0)

在我看来,您需要一个简单的锁定机制:

private Object _sync = new Object();

void MyTimerFinished() 
{
    lock (_sync)
    {
        // Access shared data
        ...
    }
}

void CodeExecutingInMainThread() 
{
    lock (_sync)
    {
        // Access shared data
        ...
    }   
}

答案 2 :(得分:0)

好的,这就是我提出的问题(lockQueue对我来说听起来有点过于复杂的解决方案 - 可能更简单但是没有尝试过)< / p>

public class ReportingTimer
{
    public event EventHandler Elapsed;
    private int _interval;
    private BackgroundWorker _worker;

    public ReportingTimer(int interval)
    {
        _interval = interval;
        _worker = new BackgroundWorker();
        _worker.WorkerReportsProgress = true;
        _worker.WorkerSupportsCancellation = true;

        _worker.DoWork += _worker_DoWork;
        _worker.ProgressChanged += _worker_ProgressChanged;

    }

    public void Start()
    {
        if (!_worker.IsBusy)
        {
            _worker.RunWorkerAsync();
        }
    }

    public void Stop()
    {
        if (_worker.IsBusy)
        {
            _worker.CancelAsync();
        }
    }

    private void _worker_DoWork(object sender, DoWorkEventArgs e)
    {

        while (!_worker.CancellationPending)
        {
            Thread.Sleep(_interval);
            _worker.ReportProgress(1);
        }

        if (_worker.CancellationPending)
        {
            e.Cancel = true;
        }
    }

    private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (!_worker.CancellationPending)
        {
            if (Elapsed != null)
            { 
                Elapsed(this, new EventArgs());
            } 

        }
    }
}

请批评。

修改:这符合我的目的,界面类似于Timer类,实际上是我想要的股票Timer