2012-12-11 49 views
1

我正在運行一個自託管的WCF服務(它將是一個Windows服務,但我正在運行它作爲一個控制檯應用程序進行調試)。服務器端代碼在調用時需要做一些工作。然後將結果同步傳回客戶端。然後,它需要進行,並做一些更密集的長時間運行處理(即異步地)WCF InstanceContextMode.PerCall服務和多線程

代碼的簡化圖示是:

[ServiceBehavior(IncludeExceptionDetailInFaults = true,InstanceContextMode = InstanceContextMode.PerCall)] 
public class MyWCFService : IMyWCFService, IDisposable { 

    private Thread importThread; 
    private DoWork importWork; 


    public MyImportResultContract StartImport(MyImportRequestContract requestParams) { 

      processorResult = new MyImportResultContract(); 


     //Simulate a short piece of work here to return results to the 
     //caller before calling a Thread to do more processing 
    processorResult.Success = true; 
    processorResult.Messages = "A message to pass back to caller" 


      Console.WriteLine("WCF Class ManagedThreadId = " + Thread.CurrentThread.ManagedThreadId); 


    //Thread off to do long running process 
      importWork = new DoWork();    
      importThread = new Thread(importWork.Start); 
      importThread.Start(); 

      //Pass back the results 
      return processorResult; 
    } 


public void Dispose() { 

     Console.WriteLine("WCF Class Dispose : " + DateTime.Now.ToLongTimeString()); 
    } 

} 


internal class DoWork : IDisposable { 

    public void Start() { 

    Console.WriteLine("Thread ManagedThreadId = " + Thread.CurrentThread.ManagedThreadId); 

    //Simulate a long running process 
     Thread.Sleep(60000); 

     Console.WriteLine("Thread Finished");    
    } 


    public void Dispose() { 

     Console.WriteLine("DoWork Class Dispose : " + DateTime.Now.ToLongTimeString()); 
    } 


}    

我有2個問題:
1。我看到在它產生的Thread之前調用的服務類的Dispose繼續並完成。我擔心的是Service類的實例可能不會因垃圾收集的線程而被釋放。這裏列出的代碼是否固定,以防止這種情況發生?

2.該服務是在Windows服務中自行託管的。如果服務停止到任何派生線程將會發生什麼?有沒有辦法讓服務等到任何線程仍然運行完成?

回答

0
  1. 當然,服務類可以在線程完成之前處理。如果你想等待線程中的工作完成,爲什麼要啓動一個線程?我不確定你期望/除了這個以外還有什麼行爲。
  2. 是的,如果進程關閉,線程就會死掉。您必須實施服務停止回調的處理程序,該處理程序會延遲關閉過程,直到所有工作人員完成爲止。如果使用更現代的Task而不是Thread,這將更容易。可能需要保留一個全局任務列表,以便您的關機代碼可以在這些任務上執行WaitAll