2014-02-28 96 views
2

我想超時並在等待指定的時間後拋出異常,並且想知道我現在正在執行的方式是否最好。超時如果方法需要太長的時間才能完成

class Timeout 
    { 

     XmlDocument doc; 
     System.Object input; 

     public Timeout(XmlDocument doc, System.Object input) 
     { 
      this.doc = doc; 
      this.input = input; 
     } 

     public void run() 
     { 
      if (input is Stream) 
      { 
       doc.Load((Stream)input); 
      } 
      else if (input is XmlReader) 
      { 
       doc.Load((XmlReader)input); 
      } 
      else if (input is TextReader) 
      { 
       doc.Load((TextReader)input); 
      } 
      else 
      { 
       doc.Load((string)input); 
      } 
      System.Threading.Thread.CurrentThread.Abort(); 
     } 

    } 

    private void LoadXmlDoc(XmlDocument doc, System.Object input) 
    { 

     Timeout timeout = new Timeout(doc, input); 
     System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run)); 
     timeoutThread.Start(); 
     System.Threading.Thread.Sleep(this.timeout * 1000); 
     if (timeoutThread.IsAlive) 
     { 
      throw new DataSourceException("timeout reached", timeout.GetHashCode()); 
     } 
    } 

這種當前的方法確實有效,所以我只是想知道是否有更簡單/更好的方式去完成相同的事情。

+1

這裏有一件事我在[MSDN](挖出http://msdn.microsoft.com/ EN-US /庫/ 5b50fdsz(v = vs.110)的.aspx)。基本上,你不需要在'run()'中放棄線程。它會拋出異常而不是完成線程。哦,除此之外,我真的不知道還有什麼可以改變的。 – bubbinator

回答

1

我最終什麼事做:

class Timeout 
    { 
     XmlDocument doc; 
     System.Object input; 

     public Timeout(XmlDocument doc, System.Object input) 
     { 
      this.doc = doc; 
      this.input = input; 
     } 

     public void run() 
     { 
      if (input is Stream) 
      { 
       doc.Load((Stream)input); 
      } 
      else if (input is XmlReader) 
      { 
       doc.Load((XmlReader)input); 
      } 
      else if (input is TextReader) 
      { 
       doc.Load((TextReader)input); 
      } 
      else 
      { 
       doc.Load((string)input); 
      } 
     } 
    } 

    private void LoadXmlDoc(XmlDocument doc, System.Object input) 
    { 
     Timeout timeout = new Timeout(doc, input); 
     System.Threading.Thread timeoutThread = new System.Threading.Thread(new ThreadStart(timeout.run)); 
     timeoutThread.Name = "XmlWorker" + threadNumber++; 
     timeoutThread.Start(); 
     if (!timeoutThread.Join(this.timeout)) //Join returning false implies the timeout was reached 
     { 
      if (timeoutThread.IsAlive) 
       timeoutThread.Abort(); 
      throw new DataConnectionException("timeout reached: " + this.timeout.Milliseconds + "ms", new TimeoutException(this.timeout.Milliseconds)); 
     } 
    } 
1

除了我的評論(here's the link from it),這裏是關於線程的some more information。基本上,它歸結爲學習不同的設計/庫,它們的優點和缺點,哪一個最適合您的需求。

從我的理解,並希望有更多關於這個主題的知識的人會對此有所瞭解,基本上有兩種不同的類別,您可以將線程設計放入同步和異步中。您已使用異步設計,使用線程池。如果你想堅持這種設計,你可以嘗試使用Task或者對於同步操作Parallel

在旁註:我不確定使用異常處理簡單邏輯背後的智慧。換句話說,exception可以簡單地替換爲返回boolean

0

試着做這樣的事情:

try 
{ 
    var cts = new System.Threading.CancellationTokenSource(); 

    cts.CancelAfter(TimeSpan.FromSeconds(0.01)); 

    var tw = Task.Run<System.Xml.XmlDocument>(() => 
    { 
     var doc = new System.Xml.XmlDocument(); 
     doc.Load("https://maps.googleapis.com/maps/api/geocode/xml?address=1+Exchange+Plaza+,+Floor+26+,+NY&sensor=false"); 
     return doc; 
    }, cts.Token); 

    var xml = await tw; 
} 
catch (TaskCanceledException e) 
{ 

} 
相關問題