取消在I / O操作中阻止的.C#Net BackgroundWorker

时间:2015-04-22 23:13:39

标签: .net backgroundworker

我需要使用Framework 3.5。我想测试另一台名为BOB的计算机上是否存在文件。我正在使用BackgroundWorker和File.Exists(fileName)。如果BOB离线,则呼叫将阻塞数十秒。当worker等待对File.Exists()的调用返回时,Abort()和Interrupt()无效。我想立即中断File.Exists()。任何人都可以建议一种不涉及p / invoke的方法吗?

感谢。

为了澄清,我需要定期检查文件是否可用。我不知道远程计算机是否配置为响应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);
        }
    }
}

3 个答案:

答案 0 :(得分:0)

请按照以下步骤操作:

  1. 首先检查远程计算机是否在线:How can I check if a computer on my network is online?

  2. 如果在线继续检查File.Exists(),则中止操作。

答案 1 :(得分:0)

虽然BackgroundWorkerCancelAsync方法,但这只是取消的请求。来自MSDN

  

工作人员代码应定期检查CancellationPending   属性,看它是否已设置为 true

显然这不适合您,因此您必须使用较低级别的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完成。

答案 2 :(得分:0)

我发布了这个问题,因为我看到如果远程计算机处于脱机状态,File.Exists会长时间阻塞。延迟发生在计算机脱机时第一次调用时。后续呼叫立即返回;似乎Widows缓存了在后续调用期间使用的东西。

如果您运行程序并切换远程计算机在启用和禁用之间的连接,您将看到程序输出的延迟。该计划的目的是说明延迟。这就是全部。

感谢大家的时间。我会根据您的意见重新考虑我的方法。