2015-04-22 41 views
-1

我需要使用Framework 3.5。我想測試另一臺名爲BOB的計算機上的文件是否存在。我正在使用BackgroundWorker和File.Exists(fileName)。如果BOB處於脫機狀態,則呼叫將阻塞數十秒鐘。工作人員正在等待File.Exists()的調用返回時,Abort()和Interrupt()不起作用。我想立即中斷File.Exists()。任何人都可以提出一種不涉及p/invoke的方法嗎?取消.C#Net BackgroundWorker在I/O操作中被阻止

謝謝。

爲了澄清,我需要定期檢查文件是否可用。我無法知道遠程計算機是否配置爲響應ping。我以標準用戶身份運行,而不是管理員。我無法訪問遠程系統管理員。

它看起來像Framework 4.0或4.5有一些異步功能,這將有助於此,但我被限制爲3.5。

編輯添加測試程序:

// First call to File.Exists waits at least 20 seconds the first time the 
// remote computer is taken off line. To demonstrate, set TestFile to the name 
// of a file on a remote computer and start the program. Then disable the 
// remote computer's network connection. Each time you disable it the test 
// program pauses. In my test the local computer runs Win8 and remote WinXp 
// in a VirtualBox VM. 
using System; 
using System.IO; 
using System.Threading; 
using System.ComponentModel; 
namespace Block2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AutoResetEvent autoResetEvent = new AutoResetEvent(false); 
      BackgroundWorker worker = new BackgroundWorker(); 
      worker.DoWork += DoWork; 
      worker.RunWorkerAsync(autoResetEvent); 
      log("main - waiting"); 
      autoResetEvent.WaitOne(); 
      log("main - finished"); 
     } 

     static void DoWork(object sender, DoWorkEventArgs e) 
     { 
      const string TestFile = @"p:\TestFile.txt"; 
      for (int x = 0; x < 100; x++) 
      { 
       if (File.Exists(TestFile)) 
        log(" -- worker: file exists"); 
       else 
        log(" -- worker: file doesn't exist"); 
       Thread.Sleep(1000); 
      } 
      ((AutoResetEvent)e.Argument).Set(); 
     } 

     static void log(string msg) 
     { 
      Console.WriteLine(DateTime.Now.ToLocalTime().ToString()+": "+ msg); 
     } 
    } 
} 
+0

啓動BackgroundWorkerThread,調用遠程計算機上未連接到網絡的文件上的File.Exists()。線程阻塞30秒或更長時間。你不能從主線程中斷它。我不認爲示例代碼會添加任何內容。呼叫塊。它不同於win32編程。什麼是-1? – Will

+0

「BackgroundWorker」的要點是它在一個單獨的線程中運行。所以如果你在'BackgroundWorker'中調用'File.Exists',它不會阻塞你的主線程。你確定你使用正確嗎?這就是爲什麼我要求你發佈你的代碼(請在你的主文章中這樣做。)另外,我不是那種低估你的代碼。 –

+0

好的,很好。沒錯,我在工作線程和該線程上調用File.Exists,而不是主線程塊。對File.Exists的調用是一個阻塞調用;我認爲工作者線程處於某個I/O掛起隊列中(而不是睡眠隊列或其他可能中斷或中止的地方)。如果在用戶界面或主線程中用戶想要退出程序,我希望能夠請求工作人員正常退出。在調用File.Exists返回之前,中止和中斷不起作用。 ***另外,有人可以在沒有說明理由的情況下對您投票而感到詭異。不太好。*** – Will

回答

0

遵循以下步驟:

  1. 首先檢查遠程計算機在線:How can I check if a computer on my network is online?

  2. 如果其在網上與檢查文件繼續.Exists(),否則中止操作。

+0

我需要定期檢查文件是否存在,因此可能是第一次,但不是之後。也就是說,如果網絡出現故障,那麼在返回之前,對File.Exists的調用需要30到60秒(取決於某個套接字超時,我假設)。謝謝。 – Will

+0

定期的意思是?多久?每次檢查File.Exists時,請檢查服務器是否在線。做一個POC,看看需要多少時間。 – Falaque

0

雖然BackgroundWorker具有CancelAsync方法,這僅僅是一個請求取消。從MSDN

工人代碼應定期檢查CancellationPending 屬性,看它是否已經被設置爲

顯然這不是您的選擇,所以您將不得不使用低級Thread構造。有一個Abort方法將終止線程。

然後,您可以更新您的主要如下:

Thread worker = new Thread(DoWork); 
worker.Start(); 
log("main - waiting"); 
log("Press any key to terminate the thread..."); 
Console.ReadKey(); 
worker.Abort(); 
log("main - finished"); 

DoWork功能是一樣的,只是它不帶任何參數。現在你的程序會在那裏檢查文件,但是如果你按下一個鍵,那麼線程將會終止。

您不能使用AutoResetEvent對象,因爲如果您這樣做,那麼您的主線程會像以前一樣阻止,直到完成DoWork

0

我發佈了這個問題,因爲我看到如果遠程計算機處於脫機狀態,File.Exists會阻塞很長一段時間。第一次在計算機處於脫機狀態時調用延遲。隨後的呼叫立即返回;它顯示Widows緩存它在隨後的調用中使用的東西。

如果您運行程序並切換啓用和禁用遠程計算機之間的連接,您將看到程序輸出中的延遲。該計劃的目的是說明這種延誤。就這樣。

謝謝大家給你的時間。我會根據您的意見重新考慮我的方法。