2012-10-14 41 views
27

Tôi đã tạo một dịch vụ cửa sổ có bộ hẹn giờ trong C# .net. nó hoạt động tốt trong khi tôi gỡ lỗi/xây dựng dự án trong studio trực quan nhưng nó không thực hiện hoạt động của nó sau khi cài đặt.Dịch vụ Windows với bộ hẹn giờ

Lý do đằng sau điều này có thể là gì?

mã:

public partial class Service1 : ServiceBase 
{ 
     FileStream fs; 
     StreamWriter m_streamWriter; 
     Timer tm = new Timer(); 

     public Service1() 
     { 
      InitializeComponent(); 

      this.ServiceName = "timerservice"; 

      tm.Interval = 2000; 
      tm.Tick += new EventHandler(PerformOperations); 
      tm.Start(); 

      fs = new FileStream(@"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write); 

      m_streamWriter = new StreamWriter(fs); 
      m_streamWriter.BaseStream.Seek(0, SeekOrigin.End); 
     } 

     private void PerformOperations(object sener, EventArgs e) 
     { 
      //StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true); 

      try 
      { 
       OdbcConnection con = new OdbcConnection("DSN=liquor_data"); 

       OdbcDataAdapter adp = new OdbcDataAdapter("", con); 

       DataSet ds = new DataSet(); 

       string sql = "select * from item_group"; 
       adp.SelectCommand.CommandText = sql; 

       adp.Fill(ds, "item_group"); 

       foreach (DataRow dr in ds.Tables["item_group"].Rows) 
       { 
        //  swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 

        //Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 
        m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); 
       } 

       m_streamWriter.Flush(); 
      } 

      catch (Exception ex) 
      { 
       // swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); } 
      } 
     } 
    } 
+0

làm tài khoản đã cho phép để chạy các dịch vụ windows sau khi cài đặt? – urlreader

+0

yes..its admin .. –

+0

Hãy thử bỏ ghi chú để xem có lỗi nào đang bị ném hay không. Ngoài ra, hãy kiểm tra nhật ký sự kiện của cửa sổ để tìm bất kỳ lỗi nào. – MattW

Trả lời

50

tiếp cận đầu tiên với Windows Service là không dễ dàng ..

Một thời gian dài trước đây, tôi đã viết một dịch vụ C#.

Đây là logic của lớp dịch vụ (thử nghiệm, hoạt động tốt):

namespace MyServiceApp 
{ 
    public class MyService : ServiceBase 
    { 
     private System.Timers.Timer timer; 

     protected override void OnStart(string[] args) 
     { 
      this.timer = new System.Timers.Timer(30000D); // 30000 milliseconds = 30 seconds 
      this.timer.AutoReset = true; 
      this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed); 
      this.timer.Start(); 
     } 

     protected override void OnStop() 
     { 
      this.timer.Stop(); 
      this.timer = null; 
     } 

     private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      MyServiceApp.ServiceWork.Main(); // my separate static method for do work 
     } 

     public MyService() 
     { 
      this.ServiceName = "MyService"; 
     } 

     // service entry point 
     static void Main() 
     { 
      System.ServiceProcess.ServiceBase.Run(new MyService()); 
     } 
    } 
} 

tôi khuyên bạn nên viết công việc dịch vụ thực sự của bạn trong một phương pháp tĩnh riêng biệt (tại sao không, trong một ứng dụng giao diện điều khiển ... chỉ cần thêm tham chiếu đến nó), để đơn giản hóa gỡ lỗi và mã dịch vụ sạch.

Đảm bảo khoảng thời gian là đủ và chỉ ghi nhật ký CHỈ trong phần ghi đè OnStart và OnStop.

Hy vọng điều này sẽ hữu ích!

+0

"và chỉ ghi nhật ký trong phần ghi đè OnStart và OnStop". Tại sao? Bạn không thể ghi vào một tập tin văn bản tại mỗi sự kiện đã hết giờ? Tôi đang gặp vấn đề đó ... Tôi có chức năng riêng của mình để ghi vào tập tin văn bản (log), nhưng nó không hoạt động (chỉ hoạt động khi bắt đầu và dừng), bạn có thể giúp tôi hiểu vấn đề là gì không? –

+0

Có, bạn cũng có thể viết vào phương thức timer_tick, nhưng đối với tôi là không cần thiết (phương pháp làm việc chính phải ghi nhật ký của nó). Bạn có thể chỉ cho tôi nhiều hơn (ngoại lệ, v.v.) không? –

7

Bạn cần phải đặt mã chính của bạn trên các phương pháp OnStart.

Điều này khác SO answer của tôi có thể hữu ích.

Bạn sẽ cần phải đặt một số mã để bật gỡ lỗi trong studio trực quan trong khi duy trì ứng dụng của bạn hợp lệ dưới dạng dịch vụ cửa sổ. Điều này khác SO thread bao gồm vấn đề gỡ lỗi một cửa sổ dịch vụ.

EDIT:

Hãy xem thêm các tài liệu có sẵn here cho phương pháp OnStart tại MSDN nơi người ta có thể đọc:

Không sử dụng các nhà xây dựng để thực hiện xử lý mà phải ở trong OnStart. Sử dụng OnStart để xử lý tất cả khởi tạo dịch vụ của bạn. Phương thức khởi tạo được gọi khi chạy thực thi của ứng dụng, không phải khi dịch vụ chạy trên . Tệp thực thi chạy trước OnStart. Khi bạn tiếp tục, ví dụ, hàm khởi tạo không được gọi lại vì SCM đã giữ đối tượng trong bộ nhớ. Nếu OnStop phát hành tài nguyên được phân bổ trong hàm dựng thay vì trong OnStart, thì cần thiết một lần nữa tài nguyên không thể tạo lại lần thứ hai dịch vụ được gọi là .

0

Dưới đây là một ví dụ làm việc, trong đó việc thực hiện các dịch vụ này được bắt đầu vào OnTimedEvent của Timer đó được thực hiện như đại biểu trong lớp ServiceBase và logic hẹn giờ được gói gọn trong một phương pháp gọi là SetupProcessingTimer():

public partial class MyServiceProject: ServiceBase 
{ 

private Timer _timer; 

public MyServiceProject() 
{ 
    InitializeComponent(); 
} 

private void SetupProcessingTimer() 
{ 
    _timer = new Timer(); 
    _timer.AutoReset = true; 
    double interval = Settings.Default.Interval; 
    _timer.Interval = interval * 60000; 
    _timer.Enabled = true; 
    _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
} 

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    // begin your service work 
    MakeSomething(); 
} 

protected override void OnStart(string[] args) 
{ 
    SetupProcessingTimer(); 
} 

... 
} 

Khoảng thời gian được định nghĩa trong app.config trong vài phút:

<userSettings> 
    <MyProject.Properties.Settings> 
     <setting name="Interval" serializeAs="String"> 
      <value>1</value> 
     </setting> 
    </MyProject.Properties.Settings> 
</userSettings> 
Các vấn đề liên quan