【问题标题】:execute a C# method asynchronously using Threading in windows service使用 Windows 服务中的线程异步执行 C# 方法
【发布时间】:2012-01-26 14:39:28
【问题描述】:

我有一个每 10 秒运行一次的 Windows 服务来执行读取方法。 Read 方法使用构造函数中提供的连接 url 连接到远程服务器。 如果远程服务器没有响应,它会抛出错误并去捕获。我们如何让线程重新开始?

class PMTicketsService
{
    private Timer _serviceTimer;
    private TimerCallback _timerDelegate;

    public PMTicketsService()
    {   
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        // Set the method to execute when the timer executes.
        _timerDelegate = new TimerCallback(Receive);

        // Create timer and attach our method delegate to it
        _serviceTimer = new Timer(_timerDelegate, null, 1000, 10000);
    }

    public void Receive(object state)
    {
        ABC abc = new ABC(Url);
        ABC abc1 = new ABC(Url1);

        /* Create the thread object, passing in the abc.Read() method
        via a ThreadStart delegate. This does not start the thread. */
        Thread oThread = new Thread(new ThreadStart(abc.Read());
        Thread oThread1 = new Thread(new ThreadStart(abc1.Read());

        // Start the thread
        oThread.Start();
        oThread1.Start();

        oThread.Join();
        oThread1.Join();
    }
}

class ABC
{
    public string strUrl;

    public ABC(string url)
    {
        strUrl = url;
    }

    public void Read()
    {
        try
        {
            // Code to use the connectionurl to access a remote server
        }
        catch (Exception ex)
        {
            // If the connection url fails to respond, how do we make thread start again?
        }
    }
}

【问题讨论】:

  • 这段代码可以进行一些清理...
  • @詹姆斯。您如何检查线程中的异常并启动另一个线程。你有代码示例吗?

标签: c# multithreading windows-services


【解决方案1】:

以后,您应该提交实际编译的示例代码。我拿走了你拥有的东西并清理了它,删除了不必要的计时器,并以一种可以满足你需要的方式来构建它。在下面的代码中,您的 Read 方法将继续运行,直到您将 done 设置为 true

    protected override void OnStart(string[] args)
    {
        try
        {
            ABC abc = new ABC("www.abc.com");

            // Create the thread object, passing in the abc.Read() method
            Thread oThread = new Thread(new ThreadStart(abc.Read));

            // Start the thread
            oThread.Start();
        }
        catch (Exception)
        {

        }
    }

    public class ABC
    {
        string strUrl = "";

        public ABC(string url)
        {
            strUrl = url;
        }

        public void Read()
        {
            bool done = false;

            while (!done)
            {
                try
                {
                    //Code to use the connectionurl to access a remote server
                    //Use strUrl in here
                }
                catch (Exception)
                {
                    //Wait 10 seconds before trying again
                    Thread.Sleep(10000);
                }

                //On success, set done to true
                done = true;
            }
        }
    }

【讨论】:

    【解决方案2】:

    为什么要开始另一个线程?启动/停止线程是一项昂贵的操作,最好保持现有线程打开并不断尝试连接(可能在两者之间进行睡眠)。你已经有了 try/catch 来防止线程崩溃。只需在一段时间内包装 try/catch (!done) 并在成功连接后将 done 设置为 true。

    您可能还想添加一些代码,以便如果您无法连续连接 X 次(可能是 5 次?),那么您将停止尝试,或者增加连接尝试之间的超时时间。

    【讨论】:

    • 我刚才已经很好地告诉了你你需要做什么,你需要做什么与线程完全无关;所有线程的东西都已经完成了。您需要定义一个布尔值,添加一个 while 循环,并可能添加一个 Thread.Sleep。这些是您需要添加的唯一代码行,我已经告诉您需要在哪里添加它们。我完全相信您可以将其转换为源代码,而无需从这里的某人那里复制/粘贴。
    猜你喜欢
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2015-10-11
    相关资源
    最近更新 更多