取消 .C# Net BackgroundWorker 在 I/O 操作上被阻止



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

谢谢。

为了澄清,我需要定期检查文件是否可用。我不知道远程计算机是否配置为响应 ping。我以标准用户而不是管理员身份运行。我无权访问远程系统管理员。

看起来框架 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);
        }
    }
}

按照以下步骤操作:

  1. 首先检查远程计算机是否联机:如何检查网络上的计算机是否联机?

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

尽管BackgroundWorker有一个CancelAsync方法,但这只是一个取消请求。从 MSDN:

工作人员代码应定期检查"取消挂起" 属性以查看它是否已设置为 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完成。

我发布了这个问题,因为我看到如果远程计算机脱机,File.Exists 会阻止很长一段时间。当计算机脱机时首次调用延迟时,会发生延迟。后续调用会立即返回;Widows 似乎缓存了它在后续调用期间使用的东西。

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

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

相关内容

  • 没有找到相关文章

最新更新