Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在windows服务中使用线程_C#_Windows_Multithreading_Windows Services - Fatal编程技术网

C# 在windows服务中使用线程

C# 在windows服务中使用线程,c#,windows,multithreading,windows-services,C#,Windows,Multithreading,Windows Services,问题?我有一个win服务,每分钟执行一个方法,示例代码: protected override void OnStart(string[] args) { //Elapsed event timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); timer.Interval = 60000; //enable timer

问题?我有一个win服务,每分钟执行一个方法,示例代码:

protected override void OnStart(string[] args)
        {

            //Elapsed event
            timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);

            timer.Interval = 60000;

            //enable timer
            timer.Enabled = true;

        }

protected override void OnStop()
        {
            timer.Enabled = false;
        }

 private void OnElapsedTime(object source, ElapsedEventArgs e)
        {

            timer.Enabled = false;

            SEND_DATA_TO_CLIENT();

            timer.Enabled = true;
        }

好的,现在该方法将_DATA_发送到_CLIENT();是一种从数据库收集数据并将其发送到客户端的方法,我必须有第二种方法PROCESS_data();一种在将数据发送到客户端之前处理数据的方法,但问题是这两种方法同时在数据库中的同一个表上工作,所以我不想得到数据库锁或其他一些数据库错误,而使用计时器则有可能使方法发生冲突,一种方法处理数据,另一种方法将数据发送到客户端,但是它们必须同时工作,也必须单独工作,有没有办法用线程来做这种事情,以及如何做?

解决问题的方法可能是使用双缓冲线程循环。 这是一个很好的实现游戏循环的概念,但也可以满足您的需要

您将有一个线程在无止境循环中执行进程数据,另一个线程在无止境循环中执行发送数据到客户端。你有两个缓冲区。这可以是任何类型的类或结构,其中包含PROCESS_DATA方法返回的信息

发送数据到客户端循环首先被锁定,直到进程数据线程填充缓冲区1。然后,进程\ u数据释放发送\ u数据\到\ u客户端的锁,并交换缓冲区。现在将数据发送到客户机,客户机拥有已填充的缓冲区,并根据需要处理数据。在此过程中,进程数据同时处理下一个数据,并等待SEND_DATA_TO_客户端完成或解锁SEND_DATA_TO_客户端以交换缓冲区

我希望你明白我的意思。如果没有,我可以给你一张照片

/// <summary>
/// Author: Samuel Egger
/// </summary>
class Program
{
    private static EventWaitHandle swappedWh = new EventWaitHandle(false, EventResetMode.AutoReset);

    private static object lockerA = new object();
    private static object lockerB = new object();

    private static int counter = 0;

    // The queues can be of any type which holds your data e.g. a struct or a class
    private static Queue<string> dataQueueA = new Queue<string>();
    private static Queue<string> dataQueueB = new Queue<string>();

    static void Main(string[] args)
    {
        Thread sendDataToClientThread = new Thread(SendDataToClient);
        Thread processDataThread = new Thread(ProcessData);

        sendDataToClientThread.IsBackground = false;

        processDataThread.Start();
        sendDataToClientThread.Start();
    }

    private static void ProcessData()
    {
        while (true)
        {
            lock (lockerA)
            {
                // Your time consuming process goes here. The result then must
                // must be saved (e.g. state) and then enqueued
                dataQueueA.Enqueue(state);
            }

            // If the operations result is equal to 2, then the render thread is done
            // and is waitung for getting unblocked
            if (Interlocked.Increment(ref counter) == 2)
            {
                counter = 0;
                SwapQueues();
                swappedWh.Set();
            }
            else
            {
                swappedWh.WaitOne();
            }
        }
    }

    private static void SendDataToClient()
    {
        while (true)
        {
            lock (lockerB)
            {
                // Send the data generated by the process data thread
                while (dataQueueB.Count > 0)
                {
                    string data = dataQueueB.Dequeue();
                    // Your process of sending the data goes here
                }
            }

            if (Interlocked.Increment(ref counter) == 2)
            {
                counter = 0;
                SwapQueues();
                swappedWh.Set();
            }
            else
            {
                swappedWh.WaitOne();
            }
        }
    }

    static void SwapQueues()
    {
        // Wait until both threads are "done" before swapping

        lock (lockerA)
        {
            lock (lockerB)
            {
                Queue<string> tmpQueue = dataQueueA;
                dataQueueA = dataQueueB;
                dataQueueB = tmpQueue;
            }
        }
    }
}
//
///作者:塞缪尔·爱格
/// 
班级计划
{
私有静态EventWaitHandle swappedWh=新的EventWaitHandle(false,EventResetMode.AutoReset);
私有静态对象lockerA=新对象();
私有静态对象lockerB=新对象();
专用静态整数计数器=0;
//队列可以是保存数据的任何类型,例如结构或类
私有静态队列dataQueueA=新队列();
私有静态队列dataQueueB=新队列();
静态void Main(字符串[]参数)
{
线程SendDataToClient线程=新线程(SendDataToClient);
线程processDataThread=新线程(ProcessData);
sendDataToClientThread.IsBackground=false;
processDataThread.Start();
sendDataToClientThread.Start();
}
私有静态void ProcessData()
{
while(true)
{
洛克(洛克时代)
{
//您耗时的过程到此结束。结果必须是
//必须保存(例如状态),然后排队
dataQueueA.Enqueue(状态);
}
//如果操作结果等于2,则渲染线程完成
//等待解除封锁
if(联锁增量(参考计数器)==2)
{
计数器=0;
SwapQueues();
swappedWh.Set();
}
其他的
{
swappedWh.WaitOne();
}
}
}
私有静态void SendDataToClient()
{
while(true)
{
锁(洛克比)
{
//发送流程数据线程生成的数据
while(dataQueueB.Count>0)
{
字符串数据=dataQueueB.Dequeue();
//您发送数据的过程如下所示
}
}
if(联锁增量(参考计数器)==2)
{
计数器=0;
SwapQueues();
swappedWh.Set();
}
其他的
{
swappedWh.WaitOne();
}
}
}
静态孔隙交换()
{
//等待两个线程“完成”后再交换
洛克(洛克时代)
{
锁(洛克比)
{
队列TMPQUE=dataQueueA;
dataQueueA=dataQueueB;
dataQueueB=tmpQueue;
}
}
}
}

我希望这个棘手的小例子能对您有所帮助。

请将您的七行句子改为一步一步地描述您的代码是什么,您希望它做什么,以及您试图让它做什么。方法中的代码是不相关的,我想做的是同时运行前面提到的方法,不是计时器而是一个线程,allI不是在谈论你的代码,而是关于你的问题的解释,这有点不清楚和不可读。干得好Sam,这就是我需要的,你能写一些代码吗?怎么做?如果你想的话,我可以在晚上给你写一些代码。目前我正在工作,没有太多的时间做这件事。没问题,不着急,我有时间,非常感谢山姆!因此,我为您添加了代码示例。请让我知道它是否有助于您的需求。非常感谢,这是一个很好的工作!!!