.NET- এ ফাইল আনলক না হওয়া পর্যন্ত অপেক্ষা করুন


103

কোনও ফাইল আনলক না হওয়া এবং পড়া এবং পুনর্নামকরণের জন্য অ্যাক্সেসযোগ্য না হওয়া পর্যন্ত থ্রেড ব্লক করার সহজ উপায় কী? উদাহরণস্বরূপ,। নেট ফ্রেমওয়ার্কের কোথাও একটি ওয়েটঅনফিল () আছে?

আমার একটি পরিষেবা আছে যা কোনও এফটিপি সাইটগুলিতে প্রেরণ করা হতে পারে এমন ফাইলগুলি সন্ধান করার জন্য একটি ফাইলসিস্টেমওয়াটার ব্যবহার করে, তবে ফাইলটি অন্য প্রক্রিয়াটি ফাইল লেখা শেষ হওয়ার আগেই ঘটায় s

আদর্শ সমাধানটির একটি সময়সীমা থাকবে তাই হাল ছেড়ে দেওয়ার আগে থ্রেড চিরতরে ঝুলবে না।

সম্পাদনা করুন: নীচের কয়েকটি সমাধানের চেষ্টা করার পরে, আমি সিস্টেমটি পরিবর্তন করে শেষ করেছি যাতে সমস্ত ফাইল লিখিত হয় Path.GetTempFileName(), তারপরে একটি File.Move()চূড়ান্ত স্থানে গিয়ে সম্পাদিত করে । যত তাড়াতাড়ি FileSystemWatcherঘটনা গুলি চালায় ফাইল আগে থেকেই সম্পূর্ণ ছিল না।


4
.NET 4.0 প্রকাশের পর থেকে, এই সমস্যাটি সমাধান করার জন্য আরও ভাল উপায় আছে?
জেসন

উত্তর:


40

এটিই একটি সম্পর্কিত প্রশ্নে আমি উত্তর দিয়েছিলাম :

    /// <summary>
    /// Blocks until the file is not locked any more.
    /// </summary>
    /// <param name="fullPath"></param>
    bool WaitForFile(string fullPath)
    {
        int numTries = 0;
        while (true)
        {
            ++numTries;
            try
            {
                // Attempt to open the file exclusively.
                using (FileStream fs = new FileStream(fullPath,
                    FileMode.Open, FileAccess.ReadWrite, 
                    FileShare.None, 100))
                {
                    fs.ReadByte();

                    // If we got this far the file is ready
                    break;
                }
            }
            catch (Exception ex)
            {
                Log.LogWarning(
                   "WaitForFile {0} failed to get an exclusive lock: {1}", 
                    fullPath, ex.ToString());

                if (numTries > 10)
                {
                    Log.LogWarning(
                        "WaitForFile {0} giving up after 10 tries", 
                        fullPath);
                    return false;
                }

                // Wait for the lock to be released
                System.Threading.Thread.Sleep(500);
            }
        }

        Log.LogTrace("WaitForFile {0} returning true after {1} tries",
            fullPath, numTries);
        return true;
    }


6
এটি কি সত্যিই সাধারণ ক্ষেত্রে কাজ করবে? আপনি যদি কোনও () ক্লজ ব্যবহার করে ফাইলটি খোলেন, ব্যবহারের সুযোগ শেষ হয়ে গেলে ফাইলটি বন্ধ এবং আনলক করা হয়। যদি এটির মতো একই কৌশল ব্যবহার করে দ্বিতীয় বার প্রক্রিয়া হয় (বারবার চেষ্টা করুন), তবে ওয়েটফোরফাইলে () প্রস্থান করার পরে, ফাইলটি খোলা যাবে কিনা তা নিয়ে একটি জাতি শর্ত রয়েছে। কোন?
চিজো

75
খারাপ ধারণা! ধারণাটি সঠিক হলেও, একটি বোলের পরিবর্তে ফাইলস্ট্রিম ফিরিয়ে দেওয়া আরও ভাল সমাধান হবে। ব্যবহারকারী যদি ফাইলটিতে তার লক আনার সুযোগ পাওয়ার আগে ফাইলটি আবার লক হয়ে থাকে - ফাংশনটি "মিথ্যা" ফিরিয়ে
দিলেও

2
ফিরোর পদ্ধতি কোথায়?
ভিবিপি

1
নিসিমের মন্তব্যটি আমি যা ভাবছিলাম তা হ'ল তবে আপনি যদি সেই সন্ধানটি ব্যবহার করতে যাচ্ছেন তবে বাইটটি পড়ার পরে 0 এ পুনরায় সেট করতে ভুলবেন না। fs.Seek (0, সিকআরগিন.বেগিন);
WHOL

73

এরিকের উত্তর থেকে শুরু করে আমি কোডটিকে আরও বেশি কমপ্যাক্ট এবং পুনরায় ব্যবহারযোগ্য করে তুলতে কিছু উন্নতি অন্তর্ভুক্ত করেছি। আশা করি এটি কার্যকর।

FileStream WaitForFile (string fullPath, FileMode mode, FileAccess access, FileShare share)
{
    for (int numTries = 0; numTries < 10; numTries++) {
        FileStream fs = null;
        try {
            fs = new FileStream (fullPath, mode, access, share);
            return fs;
        }
        catch (IOException) {
            if (fs != null) {
                fs.Dispose ();
            }
            Thread.Sleep (50);
        }
    }

    return null;
}

16
আমি ভবিষ্যতে এই কথাটি বলতে এসেছি যে এই কোডটি এখনও কবজির মতো কাজ করে। ধন্যবাদ।
ওনোসেন্দাই

6
নিখুঁতভাবে! এটি এটিকে বন্ধ করতে পারে না , কারণ এটি করা থাকলে, অন্য থ্রেডটি দৌড়ে যেতে পারে এবং উদ্দেশ্যটি পরাস্ত করে। এই প্রয়োগটি সঠিক কারণ এটি এটি খোলা রাখে! কলকারীকে এটি সম্পর্কে উদ্বিগ্ন হতে দিন, এটি নালিতে নিরাপদ using, কেবল usingব্লকের ভিতরে নালটি পরীক্ষা করুন ।
doug65536

2
"ফাইল স্ট্রিম fs = নাল;" চেষ্টা বাইরে কিন্তু জন্য ঘোষণা করা উচিত। তারপরে চেষ্টা করুন এবং ভিতরে fs ব্যবহার করুন। ক্যাচ ব্লকটি "যদি (fs! = নাল) fs.Dispose ();" করা উচিত (বা কেবল fs?। সি # 6 তে প্রেরণ করুন ()) ফাইল স্ট্রিমটি যে ফিরিয়ে দেওয়া হচ্ছে না তা সঠিকভাবে পরিষ্কার করা হয়েছে তা নিশ্চিত করতে।
বিল মিনিস

1
সত্যিই কি বাইট পড়া দরকার? আমার অভিজ্ঞতায় যদি আপনি পড়ার অ্যাক্সেসের জন্য ফাইলটি খোলেন, আপনার কাছে আছে, এটির জন্য পরীক্ষা করার দরকার নেই। যদিও এখানে নকশার সাহায্যে আপনি একচেটিয়া অ্যাক্সেস জোর করছেন না তাই এটি সম্ভব এমনকি আপনি প্রথম বাইটটি পড়তে সক্ষম হতে পারেন তবে অন্য কোনও নেই (বাইট লেভেল লকিং)। মূল প্রশ্নটি থেকে আপনি কেবল পঠনযোগ্য ভাগের স্তর দিয়ে খোলার সম্ভাবনা রয়েছে, সুতরাং অন্য কোনও প্রক্রিয়া ফাইলটি লক বা পরিবর্তন করতে পারে না। যে কোনও হারে, আমি অনুভব করি fs.ReadByte () হয় ব্যবহারের উপর নির্ভর করে একটি সম্পূর্ণ বর্জ্য, বা পর্যাপ্ত নয়।
eselk

8
ব্যবহারকারীর কোন পরিস্থিতিতে ব্লকটি fsশূন্য হতে পারে না catch? যদি FileStreamকনস্ট্রাক্টর নিক্ষেপ করে, ভেরিয়েবলটি একটি মান বরাদ্দ করা হবে না এবং এর মধ্যে আর কিছু নেই tryযা একটি নিক্ষেপ করতে পারে IOException। আমার কাছে মনে হচ্ছে ঠিক করা ঠিক হবে return new FileStream(...)
ম্যাটি ভির্ককুনেন

18

এটি করার জন্য এখানে একটি জেনেরিক কোড রয়েছে, ফাইল অপারেশন থেকে নিজেই স্বতন্ত্র। এটি কীভাবে ব্যবহার করতে হয় তার একটি উদাহরণ:

WrapSharingViolations(() => File.Delete(myFile));

অথবা

WrapSharingViolations(() => File.Copy(mySourceFile, myDestFile));

আপনি পুনরায় চেষ্টা গণনা এবং পুনরায় চেষ্টাগুলির মধ্যে অপেক্ষা করার সময়কেও সংজ্ঞায়িত করতে পারেন।

দ্রষ্টব্য: দুর্ভাগ্যক্রমে, অন্তর্নিহিত উইন 32 ত্রুটি (ERROR_SHARING_VIOLATION) .NET এর সাথে প্রকাশ করা হয়নি, তাই IsSharingViolationএটি পরীক্ষা করার জন্য প্রতিবিম্ব পদ্ধতির উপর ভিত্তি করে আমি একটি ছোট হ্যাক ফাংশন ( ) যুক্ত করেছি।

    /// <summary>
    /// Wraps sharing violations that could occur on a file IO operation.
    /// </summary>
    /// <param name="action">The action to execute. May not be null.</param>
    public static void WrapSharingViolations(WrapSharingViolationsCallback action)
    {
        WrapSharingViolations(action, null, 10, 100);
    }

    /// <summary>
    /// Wraps sharing violations that could occur on a file IO operation.
    /// </summary>
    /// <param name="action">The action to execute. May not be null.</param>
    /// <param name="exceptionsCallback">The exceptions callback. May be null.</param>
    /// <param name="retryCount">The retry count.</param>
    /// <param name="waitTime">The wait time in milliseconds.</param>
    public static void WrapSharingViolations(WrapSharingViolationsCallback action, WrapSharingViolationsExceptionsCallback exceptionsCallback, int retryCount, int waitTime)
    {
        if (action == null)
            throw new ArgumentNullException("action");

        for (int i = 0; i < retryCount; i++)
        {
            try
            {
                action();
                return;
            }
            catch (IOException ioe)
            {
                if ((IsSharingViolation(ioe)) && (i < (retryCount - 1)))
                {
                    bool wait = true;
                    if (exceptionsCallback != null)
                    {
                        wait = exceptionsCallback(ioe, i, retryCount, waitTime);
                    }
                    if (wait)
                    {
                        System.Threading.Thread.Sleep(waitTime);
                    }
                }
                else
                {
                    throw;
                }
            }
        }
    }

    /// <summary>
    /// Defines a sharing violation wrapper delegate.
    /// </summary>
    public delegate void WrapSharingViolationsCallback();

    /// <summary>
    /// Defines a sharing violation wrapper delegate for handling exception.
    /// </summary>
    public delegate bool WrapSharingViolationsExceptionsCallback(IOException ioe, int retry, int retryCount, int waitTime);

    /// <summary>
    /// Determines whether the specified exception is a sharing violation exception.
    /// </summary>
    /// <param name="exception">The exception. May not be null.</param>
    /// <returns>
    ///     <c>true</c> if the specified exception is a sharing violation exception; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsSharingViolation(IOException exception)
    {
        if (exception == null)
            throw new ArgumentNullException("exception");

        int hr = GetHResult(exception, 0);
        return (hr == -2147024864); // 0x80070020 ERROR_SHARING_VIOLATION

    }

    /// <summary>
    /// Gets the HRESULT of the specified exception.
    /// </summary>
    /// <param name="exception">The exception to test. May not be null.</param>
    /// <param name="defaultValue">The default value in case of an error.</param>
    /// <returns>The HRESULT value.</returns>
    public static int GetHResult(IOException exception, int defaultValue)
    {
        if (exception == null)
            throw new ArgumentNullException("exception");

        try
        {
            const string name = "HResult";
            PropertyInfo pi = exception.GetType().GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance); // CLR2
            if (pi == null)
            {
                pi = exception.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance); // CLR4
            }
            if (pi != null)
                return (int)pi.GetValue(exception, null);
        }
        catch
        {
        }
        return defaultValue;
    }

5
তারা সত্যিই একটি সরবরাহ করতে পারে SharingViolationException। প্রকৃতপক্ষে, তারা এখনও পিছন দিকে তুলনামূলকভাবে, যতক্ষণ না এটি নেমে আসে IOException। এবং তাদের সত্যই, সত্যই হওয়া উচিত।
রোমান স্টারকভ


9
.NET ফ্রেমওয়ার্ক 4.5,। নেট স্ট্যান্ডার্ড এবং। নেট কোর, এইচআরসাল্ট ব্যতিক্রম শ্রেণিতে একটি সর্বজনীন সম্পত্তি। এর জন্য আর প্রতিবিম্বের প্রয়োজন নেই। এমএসডিএন থেকে:Starting with the .NET Framework 4.5, the HResult property's setter is protected, whereas its getter is public. In previous versions of the .NET Framework, both getter and setter are protected.
নাইটওয়েল 888

13

আমি এই ধরণের জিনিসগুলির জন্য একটি সহায়ক ক্লাস একসাথে নিক্ষেপ করেছি। ফাইলটিতে অ্যাক্সেস করতে পারে এমন সমস্ত কিছুর উপরে যদি আপনার নিয়ন্ত্রণ থাকে তবে এটি কাজ করবে। যদি আপনি অন্যান্য কিছু জিনিস থেকে বিতর্ক আশা করেন, তবে এটি বেশ মূল্যহীন।

using System;
using System.IO;
using System.Threading;

/// <summary>
/// This is a wrapper aroung a FileStream.  While it is not a Stream itself, it can be cast to
/// one (keep in mind that this might throw an exception).
/// </summary>
public class SafeFileStream: IDisposable
{
    #region Private Members
    private Mutex m_mutex;
    private Stream m_stream;
    private string m_path;
    private FileMode m_fileMode;
    private FileAccess m_fileAccess;
    private FileShare m_fileShare;
    #endregion//Private Members

    #region Constructors
    public SafeFileStream(string path, FileMode mode, FileAccess access, FileShare share)
    {
        m_mutex = new Mutex(false, String.Format("Global\\{0}", path.Replace('\\', '/')));
        m_path = path;
        m_fileMode = mode;
        m_fileAccess = access;
        m_fileShare = share;
    }
    #endregion//Constructors

    #region Properties
    public Stream UnderlyingStream
    {
        get
        {
            if (!IsOpen)
                throw new InvalidOperationException("The underlying stream does not exist - try opening this stream.");
            return m_stream;
        }
    }

    public bool IsOpen
    {
        get { return m_stream != null; }
    }
    #endregion//Properties

    #region Functions
    /// <summary>
    /// Opens the stream when it is not locked.  If the file is locked, then
    /// </summary>
    public void Open()
    {
        if (m_stream != null)
            throw new InvalidOperationException(SafeFileResources.FileOpenExceptionMessage);
        m_mutex.WaitOne();
        m_stream = File.Open(m_path, m_fileMode, m_fileAccess, m_fileShare);
    }

    public bool TryOpen(TimeSpan span)
    {
        if (m_stream != null)
            throw new InvalidOperationException(SafeFileResources.FileOpenExceptionMessage);
        if (m_mutex.WaitOne(span))
        {
            m_stream = File.Open(m_path, m_fileMode, m_fileAccess, m_fileShare);
            return true;
        }
        else
            return false;
    }

    public void Close()
    {
        if (m_stream != null)
        {
            m_stream.Close();
            m_stream = null;
            m_mutex.ReleaseMutex();
        }
    }

    public void Dispose()
    {
        Close();
        GC.SuppressFinalize(this);
    }

    public static explicit operator Stream(SafeFileStream sfs)
    {
        return sfs.UnderlyingStream;
    }
    #endregion//Functions
}

এটি একটি নামযুক্ত মুটেক্স ব্যবহার করে কাজ করে। যারা ফাইলটি অ্যাক্সেস করতে চান তারা নামযুক্ত মুটেক্সের নিয়ন্ত্রণ অর্জনের চেষ্টা করেন, যা ফাইলটির নাম ভাগ করে দেয় ('\' এর সাথে '/' গুলি রূপান্তরিত হয়েছে)। আপনি হয় ওপেন () ব্যবহার করতে পারেন, যা মুটেক্স অ্যাক্সেসযোগ্য না হওয়া পর্যন্ত স্টল থাকবে বা আপনি ট্রিওপেন (টাইমস্প্যান) ব্যবহার করতে পারবেন, যা প্রদত্ত সময়কালের জন্য মিউটেক্স অর্জন করার চেষ্টা করে এবং সময়সীমার মধ্যে এটি অর্জন করতে না পারলে মিথ্যা ফিরিয়ে দেয়। লকগুলি যথাযথভাবে প্রকাশিত হয়েছে কিনা তা নিশ্চিত করার জন্য এটি সম্ভবত সম্ভবত ব্যবহারের ব্লকের অভ্যন্তরে ব্যবহার করা উচিত এবং যখন এই বস্তুটি নিষ্পত্তি করা হবে তখন স্ট্রিমটি (খোলা থাকলে) সঠিকভাবে নিষ্পত্তি হবে।

ফাইলটির বিভিন্ন পাঠ / লেখার জন্য আমি 20 ডলার দিয়ে একটি দ্রুত পরীক্ষা করেছি এবং কোনও দুর্নীতি দেখিনি। অবশ্যই এটি খুব উন্নত নয়, তবে এটি বেশিরভাগ সাধারণ ক্ষেত্রে কাজ করা উচিত work


5

এই বিশেষ অ্যাপ্লিকেশনটির জন্য সরাসরি ফাইলটি পর্যবেক্ষণ করা অনিবার্যভাবে বাগের সন্ধান করা শক্ত করে, বিশেষত যখন ফাইলের আকার বৃদ্ধি পায়। এখানে দুটি ভিন্ন কৌশল কার্যকর হবে।

  • দুটি ফাইল ফ্যাট করুন তবে কেবল একটি দেখুন। উদাহরণস্বরূপ ফাইলগুলি গুরুত্বপূর্ণ টেক্সট এবং গুরুত্বপূর্ণ.ফিনিশ প্রেরণ করুন। শুধুমাত্র ফিনিশ ফাইলের জন্য দেখুন তবে txt প্রক্রিয়া করুন।
  • এফটিপি একটি ফাইল কিন্তু হয়ে গেলে নামকরণ করুন। উদাহরণস্বরূপ প্রেরণ করুন গুরুত্বপূর্ণ.ওয়েট এবং প্রেরকটির নাম পরিবর্তন করে গুরুত্বপূর্ণ.txt করার পরে এটি শেষ করুন।

শুভকামনা!


এটি স্বয়ংক্রিয়র বিপরীতে। এটি আরও পদক্ষেপ সহ ম্যানুয়ালি ফাইলটি পাওয়ার মতো।
হ্যাকস্ল্যাশ

4

কিছুক্ষণ আগে আমি যে কৌশলগুলি ব্যবহার করেছি তার মধ্যে একটি ছিল আমার নিজের ফাংশনটি লেখার। মূলত ব্যতিক্রমটি ধরুন এবং একটি টাইমার ব্যবহার করে আবার চেষ্টা করুন যা আপনি একটি নির্দিষ্ট সময়কালের জন্য গুলি চালাতে পারেন। এর থেকে আরও ভাল উপায় থাকলে শেয়ার করুন।


3

এমএসডিএন থেকে :

কোনও ফাইল তৈরি হওয়ার সাথে সাথে অনক্রিয়েটেড ইভেন্টটি উত্থাপিত হয়। যদি কোনও ফাইল অনুলিপি করা হয় বা একটি পর্যবেক্ষণ ডিরেক্টরিতে স্থানান্তরিত করা হয়, তবে অনক্র্রেটেড ইভেন্টটি তত্ক্ষণাত উত্থাপিত হবে, তারপরে এক বা একাধিক অন-চেঞ্জ হওয়া ইভেন্ট।

আপনার ফাইলসিস্টেমওয়াটারকে এমন পরিবর্তন করা যেতে পারে যাতে এটি "অনক্রিয়েটেড" ইভেন্টের সময় এর পঠন / পুনর্নবীকরণ না করে, বরং:

  1. একটি থ্রেড বিস্তৃত করে যা লক না হওয়া অবধি ফাইলের স্থিতি পোল করে (একটি ফাইলআইএনফো অবজেক্ট ব্যবহার করে)
  2. ফাইলটি আর লক করা নেই এবং যেতে প্রস্তুত হয় তা নির্ধারণ করার সাথে সাথেই ফাইলটি প্রক্রিয়া করার জন্য সেবার সাথে কল করে

1
ফাইলসাইমওয়াতচারের থ্রেড বিচ্ছিন্নকরণটি অন্তর্নিহিত বাফারকে ওভারফ্লোতে নিয়ে যেতে পারে, ফলে পরিবর্তিত ফাইলগুলির অনেকগুলি অনুপস্থিত। গ্রাহক / প্রযোজক সারি তৈরি করা আরও ভাল পদ্ধতির হবে।
নিসিম

2

বেশিরভাগ ক্ষেত্রে @harpo প্রস্তাবিত সহজ পদ্ধতির কাজ করবে। আপনি এই পদ্ধতির ব্যবহার করে আরও পরিশীলিত কোড বিকাশ করতে পারেন:

  • সিস্টেমহ্যান্ডলিআইফরমেশন \ সিস্টেমপ্রসেস ইনফরমেশন ব্যবহার করে নির্বাচিত ফাইলের জন্য সমস্ত খোলা হ্যান্ডলগুলি সন্ধান করুন
  • এর অভ্যন্তরীণ হ্যান্ডেলটিতে অ্যাক্সেস পেতে সাবক্লাস অপেক্ষা করুন হ্যান্ডল ক্লাস
  • পাসটি হ'ল হ্যান্ডলগুলিকে উপক্লাসড ওয়েটহ্যান্ডলে মোড়ানো ওয়েটহ্যান্ডল থেকে পাওয়া গেছে। ওয়েইটএইন পদ্ধতিতে

2

ট্রান্সফার প্রক্রিয়া ট্রিগার ফাইল SameNameASTrasferedFile.trg ফাইল ট্রান্সমিশন শেষ হওয়ার পরে তৈরি করা হয়।

তারপরে ফাইলসিস্টেমওয়াটার সেটআপ করুন যা কেবল * .trg ফাইলে ইভেন্ট চালিত করে।


1

ফাইলটির লক স্থিতি নির্ধারণ করতে আপনি কী ব্যবহার করছেন তা আমি জানি না, তবে এর মতো কিছু করা উচিত।

যখন (সত্য)
{
    চেষ্টা করুন
        স্ট্রিম = ফাইল.অপেন (ফাইলের নাম, ফাইলমোড);
        বিরতি;
    }
    ধরা (ফাইলআইওএক্সেপশন) {

        // এটি লক সমস্যা কিনা তা পরীক্ষা করে দেখুন

        থ্রেড.স্লিপ (100);
    }
}

1
কিছুটা দেরি হলেও ফাইলটি কোনওভাবে লক হয়ে গেলে আপনি কখনই আপনার লুপ থেকে প্রস্থান করতে পারবেন না। আপনার একটি কাউন্টার যুক্ত করা উচিত (প্রথম উত্তর দেখুন)।
পিটার

0

একটি সম্ভাব্য সমাধান হ'ল, কিছু ভোটদানের সাথে একটি ফাইল সিস্টেমওয়াতচারকে একত্রিত করা,

একটি ফাইলের প্রতিটি পরিবর্তনের জন্য বিজ্ঞপ্তি পান এবং বর্তমানে গৃহীত উত্তরে বর্ণিত হিসাবে এটি লক করা হয়েছে কিনা তা বিজ্ঞপ্তি পাওয়ার পরে: https://stackoverflow.com/a/50800/6754146 ফাইলপ্রবাহটি খোলার কোডটি উত্তর থেকে অনুলিপি করা হয়েছে এবং সামান্য পরিবর্তিত:

public static void CheckFileLock(string directory, string filename, Func<Task> callBack)
{
    var watcher = new FileSystemWatcher(directory, filename);
    FileSystemEventHandler check = 
        async (sender, eArgs) =>
    {
        string fullPath = Path.Combine(directory, filename);
        try
        {
            // Attempt to open the file exclusively.
            using (FileStream fs = new FileStream(fullPath,
                    FileMode.Open, FileAccess.ReadWrite,
                    FileShare.None, 100))
            {
                fs.ReadByte();
                watcher.EnableRaisingEvents = false;
                // If we got this far the file is ready
            }
            watcher.Dispose();
            await callBack();
        }
        catch (IOException) { }
    };
    watcher.NotifyFilter = NotifyFilters.LastWrite;
    watcher.IncludeSubdirectories = false;
    watcher.EnableRaisingEvents = true;
    //Attach the checking to the changed method, 
    //on every change it gets checked once
    watcher.Changed += check;
    //Initially do a check for the case it is already released
    check(null, null);
}

এই পদ্ধতিতে আপনি কোনও ফাইলকে লক করা হয়েছে কিনা তা সুনির্দিষ্ট কলব্যাকের মাধ্যমে বন্ধ হয়ে যাওয়ার পরে বিজ্ঞপ্তি পেতে পারেন, এইভাবে আপনি অত্যধিক আক্রমণাত্মক পোলিং এড়াতে পারবেন এবং কেবল যখন কাজটি বন্ধ হয়ে যাবে তখনই কাজটি করুন


-1

আমি গুলজারের মতোই এটি করি, কেবল একটি লুপ দিয়ে চেষ্টা করতে থাকি।

আসলে আমি ফাইল সিস্টেম প্রহরীকেও বিরক্ত করি না। এক মিনিটের মধ্যে একবারে নতুন ফাইলগুলির জন্য একটি নেটওয়ার্ক ড্রাইভ পোলিং করা সস্তা।


2
এটি সস্তা হতে পারে তবে একবারে এক মিনিট প্রচুর অ্যাপ্লিকেশনের জন্য খুব দীর্ঘ। রিয়েল টাইম মনিটরিং কখনও কখনও প্রয়োজন। পরিবর্তে আপনাকে এমন কিছু বাস্তবায়ন করতে হবে যা সি # তে ফাইল সিস্টেমের বার্তাগুলি শুনবে (এই জিনিসগুলির জন্য সবচেয়ে সুবিধাজনক ভাষা নয়) আপনি এফএসডাব্লু ব্যবহার করেন।
থান্ডারগ্রি

-1

পরিবর্তিত ইভেন্টটি কেবলমাত্র নোটিফিলার নোটিফাইফিল্টারগুলি ব্যবহার করুন ast লাইজ রাইট :

var watcher = new FileSystemWatcher {
      Path = @"c:\temp\test",
      Filter = "*.xml",
      NotifyFilter = NotifyFilters.LastWrite
};
watcher.Changed += watcher_Changed; 
watcher.EnableRaisingEvents = true;

1
ফাইলসিস্টেমওয়াটার কেবল তখনই জানায় না যখন কোনও ফাইল লিখিত হয়ে যায়। এটি "একক" যৌক্তিক লেখার জন্য আপনাকে প্রায়শই বার অবহিত করবে এবং আপনি যদি প্রথম বিজ্ঞপ্তি পাওয়ার পরে ফাইলটি খোলার চেষ্টা করেন তবে আপনি একটি ব্যতিক্রম পাবেন।
রস

-1

একটি দৃষ্টিভঙ্গি সংযুক্তি যুক্ত করার সময় আমি একই ধরণের সমস্যায় পড়েছি। "ব্যবহার" দিনটি সংরক্ষণ করেছে।

string fileName = MessagingBLL.BuildPropertyAttachmentFileName(currProp);

                //create a temporary file to send as the attachment
                string pathString = Path.Combine(Path.GetTempPath(), fileName);

                //dirty trick to make sure locks are released on the file.
                using (System.IO.File.Create(pathString)) { }

                mailItem.Subject = MessagingBLL.PropertyAttachmentSubject;
                mailItem.Attachments.Add(pathString, Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing);

-3

বিকল্প হিসাবে এটি সম্পর্কে কীভাবে:

private void WaitOnFile(string fileName)
{
    FileInfo fileInfo = new FileInfo(fileName);
    for (long size = -1; size != fileInfo.Length; fileInfo.Refresh())
    {
        size = fileInfo.Length;
        System.Threading.Thread.Sleep(1000);
    }
}

অবশ্যই যদি ফাইলসাইজটি তৈরির পূর্বনির্ধারিত হয় তবে আপনি একটি মিথ্যা ধনাত্মক পেতেন।


1
যদি ফাইলটিতে লেখার প্রক্রিয়াটি এক সেকেন্ডের বেশি বিরতি দেয় বা মেমরির এক সেকেন্ডেরও বেশি সময় ধরে বিরতি দেয় তবে আপনি আর একটি মিথ্যা ইতিবাচক পাবেন। আমি মনে করি না যে এটি কোনও পরিস্থিতিতেই ভাল সমাধান।
ক্রিস ওয়েনহ্যাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.