ගොනුවක් භාවිතයේ තිබේදැයි පරීක්ෂා කිරීමට ක්‍රමයක් තිබේද?


862

මම C # හි වැඩසටහනක් ලියන අතර එය නැවත 1 රූප ගොනුවකට ප්‍රවේශ විය යුතුය. බොහෝ විට එය ක්‍රියාත්මක වේ, නමුත් මගේ පරිගණකය වේගයෙන් ක්‍රියාත්මක වන්නේ නම්, එය නැවත ගොනු පද්ධතියට සුරැකීමට පෙර ගොනුව වෙත ප්‍රවේශ වීමට උත්සාහ කර දෝෂයක් ඇති කරයි: "වෙනත් ක්‍රියාවලියක් මඟින් ගොනුව භාවිතයේ පවතී" .

මම මේ සඳහා මගක් සෙවීමට කැමතියි, නමුත් මගේ සියලු ගූග්ලිං මඟින් ව්‍යතිරේඛ හැසිරවීම් භාවිතා කරමින් චෙක්පත් නිර්මාණය කර ඇත. මෙය මගේ ආගමට විරුද්ධ ය, එබැවින් මම කල්පනා කරමින් සිටියේ යමෙකුට එය කිරීමට වඩා හොඳ ක්‍රමයක් තිබේද?


30
හරි, පද්ධතියේ ඇති සියලුම විවෘත හැසිරවීම් පරීක්ෂා කිරීමෙන් ඔබට එය පරීක්ෂා කළ හැකිය. කෙසේ වෙතත්, වින්ඩෝස් බහු කාර්ය මෙහෙයුම් පද්ධතියක් බැවින්, ඔබ කේතය ධාවනය කළ විගසම ගොනුව විවෘතව තිබේද යන්න තීරණය කිරීමට අවස්ථාවක් තිබේ, එය එසේ නොවේ යැයි ඔබ සිතන්නේ නම්, ක්‍රියාවලි කේතයක් එම ගොනුව භාවිතා කිරීම ආරම්භ කරයි, පසුව ඔබ උත්සාහ කරන කාලය වන විට එය භාවිතා කරන්න, ඔබට දෝෂයක් ලැබේ. එහෙත්, පළමුව පරීක්ෂා කිරීමේ වරදක් නැත; ඔබට එය ඇත්ත වශයෙන්ම අවශ්‍ය වූ විට එය භාවිතයේ නැතැයි නොසිතන්න.
බොබීෂාෆ්ටෝ

3
නමුත් මෙම විශේෂිත කාරණය සඳහා පමණි; ලිපිගොනු හසුරුවීම් පරීක්ෂා නොකිරීමට මම නිර්දේශ කරමි. පෙර සැකසූ වාර ගණනක් උත්සාහ කරන්න, අසමත් වීමට පෙර 3-5 කියන්න.
බොබීෂාෆ්ටෝ

මෙම රූප ගොනුව ජනනය කරන්නේ කෙසේද? පරම්පරාව අවසන් වන තුරු ඔබේ වැඩසටහන නැවැත්වීමට / නිදා ගැනීමට / විරාමයක් තැබිය හැකිද? එය බොහෝ දුරට තත්වය හැසිරවීමට වඩා උසස් ක්‍රමයකි. එසේ නොවේ නම්, ව්‍යතිරේක හැසිරවීම භාවිතා කිරීමෙන් වැළකී සිටිය හැකි යැයි මම නොසිතමි.
කැච්වා

සියල්ලන්ම ව්‍යතිරේක භාවිතා කිරීම යම්කිසි උපකල්පනයක් පරීක්ෂා කිරීම භයානක දෙයක් විය හැකි අතරම හිතාමතාම අසාර්ථක වීමේ හැකියාව බැහැර නොකරයිද?
jwg

26
ඔබේ දර්ශනයට ව්‍යතිරේක පිළිබඳ වැරදි අවබෝධයක් ඇත. බොහෝ අය සිතන්නේ ව්‍යතිරේකයන් යනු ශුද්ධ-කපටිකම-විනාශයෙන්-යමක්-වැරදි-මියය-මියය-මිය යන බවය. ව්‍යතිරේකය යන්නෙන් අදහස් වන්නේ .... ව්‍යතිරේකය. එයින් අදහස් කරන්නේ ඔබට "හැසිරවීමට" (හෝ ගිණුමට) අවශ්‍ය වූ සුවිශේෂී දෙයක් සිදුව ඇති බවයි. සමහර විට ඔබට දත්ත ප්‍රවේශය සඳහා නැවත උත්සාහ කිරීමට අවශ්‍ය විය හැකිය, ඔබට සම්බන්ධතාවයක් ලබා ගත නොහැකි බව පරිශීලකයා දැන සිටිය යුතුය. ඔයා මොකද කරන්නේ? ඔබ ConnectionFailedException හසුරුවන අතර පරිශීලකයාට දන්වනු ඇත, එබැවින් සමහර විට ඔවුන් පැයකට පසු උත්සාහ කිරීම නවත්වනු ඇති අතර කේබලය විසන්ධි කර ඇති බව දකියි.
ලී ලුවියර්

Answers:


558

මෙම විසඳුම පිළිබඳ සටහන යාවත්කාලීන කරන ලදි : FileAccess.ReadWriteකියවීම-පමණක් ගොනු සඳහා පරීක්ෂා කිරීම අසාර්ථක වන අතර එමඟින් පරීක්ෂා කිරීම සඳහා විසඳුම වෙනස් කර ඇත FileAccess.Read. මෙම විසඳුම ක්‍රියාත්මක වන බැවින් FileAccess.Readගොනුවේ ලිවීමට හෝ කියවීමට අගුලක් තිබේ නම් පරීක්ෂා කිරීමට උත්සාහ කිරීම අසාර්ථක වනු ඇත, කෙසේ වෙතත්, ගොනුවේ ලිවීමේ හෝ කියවීමේ අගුලක් නොමැති නම් මෙම විසඳුම ක්‍රියා නොකරනු ඇත, එනම් එය විවෘත කර ඇත (කියවීම හෝ ලිවීම සඳහා) FileShare.Read හෝ FileShare.Write ප්‍රවේශය සමඟ.

මුල්: මම පසුගිය වසර කිහිපය තුළ මෙම කේතය භාවිතා කර ඇති අතර, ඒ සමඟ මට කිසිදු ගැටළුවක් නොමැත.

ව්‍යතිරේක භාවිතා කිරීම පිළිබඳ ඔබේ පැකිලීම තේරුම් ගන්න, නමුත් ඔබට ඒවා සැමවිටම මග හැරිය නොහැක:

protected virtual bool IsFileLocked(FileInfo file)
{
    try
    {
        using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
        {
            stream.Close();
        }
    }
    catch (IOException)
    {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    }

    //file is not locked
    return false;
}

60
මෙය හොඳ විසඳුමක්, නමුත් මට එක අදහසක් ඇත - ඔබට ගොනුව ප්‍රවේශ ප්‍රකාරය සමඟ විවෘත කිරීමට අවශ්‍ය නොවනු ඇත. FileAccess. ගොනුව කියවීමට පමණක් සිදුවුවහොත් ReadWrite සැමවිටම අසාර්ථක වනු ඇත.
adeel825

221
-1. මෙය දුර්වල පිළිතුරකි, මන්ද යත්, ගොනුව IsFileLocked හි වසා දැමීමෙන් පසුව වෙනත් නූලකින් / ක්‍රියාවලියකින් එය අගුළු දැමිය හැකි අතර ඔබේ නූල් විවෘත කිරීමට පෙර එය විවෘත වේ.
පොලිෆන්

18
මම හිතන්නේ මේක හොඳ පිළිතුරක්. මම මෙය දිගු කිරීමේ ක්‍රමයක් ලෙස භාවිතා කරමි á la public static bool IsLocked(this FileInfo file) {/*...*/}.
මැනුසෝර්

54
H ක්‍රිස්ඩබ්ලිව්: ඔබ කල්පනා කරනවා සිදුවන්නේ කුමක්ද කියා. කලබල නොවන්න. ඔබ දැන් ඩේලි ඩබ්ලිව්ටීඑෆ්
පියරේ ලෙබොපින්

16
H ක්‍රිස්ව් ඇයි ඒක නරක දෙයක්. හොඳ සහ නරක පිළිතුරු පෙන්වා දීමට මෙම ප්‍රජාව මෙහි සිටී. වෘත්තිකයන් පිරිසක් මෙය නරක දෙයක් බව දැක, පහත් කොට සැලකීමට සම්බන්ධ වන්නේ නම්, එම වෙබ් අඩවිය WAI වේ. ඔබ negative ණාත්මක වීමට පෙර, ඔබ එම ලිපිය කියවන්නේ නම්, ඔවුන් පවසන්නේ “නිවැරදි පිළිතුර ඉහළට ඔසවා තබන්න” කියා වැරදි පිළිතුර අවතක්සේරු නොකරන්න. අදහස් දැක්වීමේදී ද ඔවුන්ගේ අදහස් පැහැදිලි කිරීමට ඔබට අවශ්‍යද? වෙනත් හොඳ වෙබ් අඩවියකට මාව හඳුන්වා දීම ගැන ස්තූතියි!
ලී ලුවියර්

573

ඔබට මෙය නූල් ධාවන තත්වයකින් පීඩා විඳින්න පුළුවන්, මෙය ආරක්ෂක අවදානමක් ලෙස භාවිතා කරන බවට ලේඛනගත උදාහරණ ඇත. ගොනුව තිබේදැයි ඔබ පරීක්ෂා කළත්, එය උත්සාහ කර භාවිතා කර ඔබට එම අවස්ථාවේදී විසි කළ හැකිය, අනිෂ්ට පරිශීලකයෙකුට ඔබේ කේතය බලහත්කාරයෙන් හා සූරාකෑමට භාවිතා කළ හැකිය.

ඔබගේ හොඳම ඔට්ටුව උත්සාහක දිනුම් / අවසානයේ ගොනු හසුරුව ලබා ගැනීමට උත්සාහ කරයි.

try
{
   using (Stream stream = new FileStream("MyFilename.txt", FileMode.Open))
   {
        // File/Stream manipulating code here
   }
} catch {
  //check here why it failed and ask user to retry if the file is in use.
}

129
+1. "ගොනුවක් භාවිතයේ තිබේදැයි ඉගෙන ගැනීමට" 100% ආරක්ෂිත ක්‍රමයක් නොමැත, මන්ද ඔබ පරීක්ෂා කිරීමෙන් පසු මිලි තත්පර, ගොනුව තවදුරටත් භාවිතයේ නොතිබිය හැකිය, නැතහොත් අනෙක් අතට. ඒ වෙනුවට, ඔබ ගොනුව විවෘත කර ව්‍යතිරේකයක් නොමැති නම් එය භාවිතා කරන්න.
සෙඩාත් කපනොග්ලු

9
ඉතා නරකයි .NET CAS සඳහා සහය නොදක්වයි. සාර්ථකත්වය / අසාර්ථකත්වය ලබා දෙන ට්‍රයි ඕපන් ෆයිල් (Ref FileHandle) වැනි දෙයක්. ව්‍යතිරේක හැසිරවීම මත පමණක් රඳා නොසිට වැඩ කරන සෑම විටම සිටිය යුතුය. මයික්‍රොසොෆ්ට් ඔෆිස් එය කරන්නේ කෙසේදැයි මම කල්පනා කරමි.
TamusJRoyce

2
මෙහිදී තේරුම් ගත යුතු ප්‍රධානම දෙය නම් මෙම API හුදෙක් වින්ඩෝස් ඒපීඅයි භාවිතා කරමින් ගොනු හසුරුවීමක් ලබා ගැනීමයි. එනිසා ඔවුන්ට සී ඒපීඅයි වෙතින් ලැබුණු දෝෂ කේතය පරිවර්තනය කර එය විසි කිරීම සඳහා ව්‍යතිරේකයකට ඔතා තිබිය යුතුය. .Net හි අපට ව්‍යතිරේක හැසිරවීමක් ඇත, එබැවින් එය භාවිතා නොකරන්න. එමඟින් ඔබට ඔබේ කේතයේ පිරිසිදු ඉදිරි මාවතක් ලිවිය හැකි අතර දෝෂ හැසිරවීම වෙනම කේත මාර්ගයක තබන්න.
ස්පෙන්ස්

37
භාවිතා කිරීමේ ප්‍රකාශය නම් මා අවසන් වූ පසු ධාරාව වසා ඇති බව සහතික කිරීමයි. () {Use භාවිතා කිරීම try} අවසාන වශයෙන් {obj.Dispose () try උත්සාහ කිරීමට වඩා අඩු අක්ෂර බව ඔබට වැටහෙනු ඇතැයි මම සිතමි. ඔබ දැන් ඔබේ වස්තු යොමු කිරීම භාවිතා කරන ප්‍රකාශයෙන් පිටත ප්‍රකාශ කළ යුතු බව ඔබට පෙනී යනු ඇත, එය වඩාත් ටයිප් කිරීමකි. ඔබට පැහැදිලි අතුරු මුහුණතක් තිබේ නම් ඔබට ද දැමිය යුතුය. අවසාන වශයෙන් ඔබට ASAP බැහැර කිරීමට අවශ්‍ය වන අතර අවසාන වශයෙන් තර්කනයට UI හෝ වෙනත් දිගුකාලීන ක්‍රියාමාර්ග තිබිය හැක. </rant>
ස්පෙන්ස්

2
එමඟින් ඔබ ඔබේ වස්තුව උත්සාහයෙන් පරිබාහිරව ප්‍රකාශ කළ යුතු අතර බැහැර කිරීම සඳහා පැහැදිලිවම ඇමතිය යුතුය. එය භාවිතා කිරීම ඔබ වෙනුවෙන් කරන අතර එකම දෙය අදහස් කරයි.
ස්පෙන්ස්

93

ගොනුවක් අගුළු දමා ඇත්දැයි පරීක්ෂා කිරීමට මෙය භාවිතා කරන්න:

using System.IO;
using System.Runtime.InteropServices;
internal static class Helper
{
const int ERROR_SHARING_VIOLATION = 32;
const int ERROR_LOCK_VIOLATION = 33;

private static bool IsFileLocked(Exception exception)
{
    int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
}

internal static bool CanReadFile(string filePath)
{
    //Try-Catch so we dont crash the program and can check the exception
    try {
        //The "using" is important because FileStream implements IDisposable and
        //"using" will avoid a heap exhaustion situation when too many handles  
        //are left undisposed.
        using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) {
            if (fileStream != null) fileStream.Close();  //This line is me being overly cautious, fileStream will never be null unless an exception occurs... and I know the "using" does it but its helpful to be explicit - especially when we encounter errors - at least for me anyway!
        }
    }
    catch (IOException ex) {
        //THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
        if (IsFileLocked(ex)) {
            // do something, eg File.Copy or present the user with a MsgBox - I do not recommend Killing the process that is locking the file
            return false;
        }
    }
    finally
    { }
    return true;
}
}

කාර්ය සාධන හේතූන් මත එකම මෙහෙයුමේ ගොනු අන්තර්ගතය කියවීමට මම නිර්දේශ කරමි. මෙන්න උදාහරණ කිහිපයක්:

public static byte[] ReadFileBytes(string filePath)
{
    byte[] buffer = null;
    try
    {
        using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            int length = (int)fileStream.Length;  // get file length
            buffer = new byte[length];            // create buffer
            int count;                            // actual number of bytes read
            int sum = 0;                          // total number of bytes read

            // read until Read method returns 0 (end of the stream has been reached)
            while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
                sum += count;  // sum is a buffer offset for next reading

            fileStream.Close(); //This is not needed, just me being paranoid and explicitly releasing resources ASAP
        }
    }
    catch (IOException ex)
    {
        //THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
        if (IsFileLocked(ex))
        {
            // do something? 
        }
    }
    catch (Exception ex)
    {
    }
    finally
    {
    }
    return buffer;
}

public static string ReadFileTextWithEncoding(string filePath)
{
    string fileContents = string.Empty;
    byte[] buffer;
    try
    {
        using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            int length = (int)fileStream.Length;  // get file length
            buffer = new byte[length];            // create buffer
            int count;                            // actual number of bytes read
            int sum = 0;                          // total number of bytes read

            // read until Read method returns 0 (end of the stream has been reached)
            while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
            {
                sum += count;  // sum is a buffer offset for next reading
            }

            fileStream.Close(); //Again - this is not needed, just me being paranoid and explicitly releasing resources ASAP

            //Depending on the encoding you wish to use - I'll leave that up to you
            fileContents = System.Text.Encoding.Default.GetString(buffer);
        }
    }
    catch (IOException ex)
    {
        //THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
        if (IsFileLocked(ex))
        {
            // do something? 
        }
    }
    catch (Exception ex)
    {
    }
    finally
    { }     
    return fileContents;
}

public static string ReadFileTextNoEncoding(string filePath)
{
    string fileContents = string.Empty;
    byte[] buffer;
    try
    {
        using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            int length = (int)fileStream.Length;  // get file length
            buffer = new byte[length];            // create buffer
            int count;                            // actual number of bytes read
            int sum = 0;                          // total number of bytes read

            // read until Read method returns 0 (end of the stream has been reached)
            while ((count = fileStream.Read(buffer, sum, length - sum)) > 0) 
            {
                sum += count;  // sum is a buffer offset for next reading
            }

            fileStream.Close(); //Again - this is not needed, just me being paranoid and explicitly releasing resources ASAP

            char[] chars = new char[buffer.Length / sizeof(char) + 1];
            System.Buffer.BlockCopy(buffer, 0, chars, 0, buffer.Length);
            fileContents = new string(chars);
        }
    }
    catch (IOException ex)
    {
        //THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
        if (IsFileLocked(ex))
        {
            // do something? 
        }
    }
    catch (Exception ex)
    {
    }
    finally
    {
    }

    return fileContents;
}

එය ඔබම අත්හදා බලන්න:

byte[] output1 = Helper.ReadFileBytes(@"c:\temp\test.txt");
string output2 = Helper.ReadFileTextWithEncoding(@"c:\temp\test.txt");
string output3 = Helper.ReadFileTextNoEncoding(@"c:\temp\test.txt");

8
එහි එහි දී නම් "බොහෝ මැජික් අංක" නොවේ නම් මම upvote ඇත en.wikipedia.org/wiki/Magic_number_(programming)
තරහක්

3
මා සඳහන් කළේ දෝෂ කේත සැසඳීම් මිස බිට් මාරුව නොවේ. දැන් ඔබ එය සඳහන් කළත් ...
ක්‍රිස්

1
ඔබේ ඇල්ල IOExceptionසාමාන්‍යයෙන් විය යුතු Exceptionඅතර පසුව වර්ගය පිළිබඳ පරීක්ෂණයක් කළ යුතුය.
Askolein

3
Ere ජෙරමි තොම්සන් කනගාටුවට කරුණක් නම් ඔබ IOExceptionඑය සාමාන්‍ය දෙයට පසුව තැබීමයි . සාමාන්‍ය තැනැත්තා පසුකර යන සෑම දෙයක්ම අල්ලා ගන්නා අතර නිශ්චිත IOExceptionසෑම විටම තනිකමකි. දෙක මාරු කරන්න.
Askolein

මම මේ විසඳුමට කැමතියි. තවත් එක් යෝජනාවක්: අල්ලා ගැනීමේදී වෙනත් අයෙකු ලෙස (IsFileLocked (උදා)) මම හිටපු විසි කරන්නෙමි. මෙය ව්‍යතිරේකය විසි කිරීමෙන් ගොනුව නොපවතින අවස්ථාව (හෝ වෙනත් IOException) හසුරුවනු ඇත.
shindigo

7

ව්යතිරේකය අපේක්ෂිත පරිදි භාවිතා කරන්න. ගොනුව භාවිතයේ පවතින බව පිළිගෙන ඔබේ ක්‍රියාව අවසන් වන තුරු නැවත නැවත උත්සාහ කරන්න. මෙය වඩාත් කාර්යක්ෂම වන්නේ ඔබ ක්‍රියා කිරීමට පෙර රාජ්‍යය පරීක්ෂා කරන කිසිදු චක්‍රයක් නාස්ති නොකරන බැවිනි.

උදාහරණයක් ලෙස පහත ශ්‍රිතය භාවිතා කරන්න

TimeoutFileAction(() => { System.IO.File.etc...; return null; } );

තත්පර 2 කට පසු නැවත භාවිතා කළ හැකි ක්‍රමය

private T TimeoutFileAction<T>(Func<T> func)
{
    var started = DateTime.UtcNow;
    while ((DateTime.UtcNow - started).TotalMilliseconds < 2000)
    {
        try
        {
            return func();                    
        }
        catch (System.IO.IOException exception)
        {
            //ignore, or log somewhere if you want to
        }
    }
    return default(T);
}

6

සමහර විට ඔබට FileSystemWatcher භාවිතා කර වෙනස් කළ සිදුවීම නැරඹිය හැකිය.

මම මෙය මා විසින්ම භාවිතා කර නැත, නමුත් එය වෙඩි තැබීම වටී. මෙම නඩුව සඳහා ගොනු පද්ධති මුරකරු තරමක් බරින් යුක්ත නම්, මම උත්සාහ / අල්ලා / නිදාගැනීමේ ලූපය සඳහා යන්නෙමි.


1
FileSystemWatcher භාවිතා කිරීම උදව් නොකරයි, මන්ද නිර්මාණය කරන ලද සහ වෙනස් කරන ලද සිදුවීම් ගොනු නිර්මාණය / වෙනස් කිරීම ආරම්භයේදීම මතු වේ. .NET යෙදුමට FileSystemEventHandler Callback හරහා ක්‍රියාත්මක වීමට වඩා කුඩා ලිපිගොනු පවා මෙහෙයුම් පද්ධතිය විසින් ලිවීමට හා වසා දැමීමට වැඩි කාලයක් අවශ්‍ය වේ. මෙය ඉතා කණගාටුදායක ය, නමුත් ගොනුවට ප්‍රවේශ වීමට පෙර රැඳී සිටීමේ කාලය තක්සේරු කිරීම හෝ ව්‍යතිරේක ලූප වෙත ධාවනය කිරීම හැර වෙනත් විකල්පයක් නොමැත ...

FileSystemWatcher එකවර බොහෝ වෙනස්කම් හසුරුවන්නේ නැත, එබැවින් ඒ ගැන සැලකිලිමත් වන්න.
බෙන් එෆ්

1
බීටීඩබ්ලිව්, එම්එස් තමන්ගේම එෆ්එස්ඩබ්ලිව් “ෆයිල් සිස්ටම් වදර්” ලෙස හඳුන්වන නූල් නිදොස් කිරීමේදී හා නරඹමින් සිටියදී ඔබ දැක තිබේද? කෙසේ වෙතත් වොදර් එකක් යනු කුමක්ද?
devlord

හරියටම මට මෙම ගැටළුව ඇති වූයේ ගොනුව වසා දැමීමට පෙර FileSystemWatcher සමඟ වින්ඩෝස් සේවාවක් ගොනුව කියවීමට උත්සාහ කරන බැවිනි.
සංවර්ධක

6

ඔබට කාර්යයක් ලබා දුන් විගස එය නැවත ලබා දිය හැකිය. එය සරල විසඳුමක්, නමුත් එය හොඳ ආරම්භක ස්ථානයකි. එය නූල් ආරක්ෂිතයි.

private async Task<Stream> GetStreamAsync()
{
    try
    {
        return new FileStream("sample.mp3", FileMode.Open, FileAccess.Write);
    }
    catch (IOException)
    {
        await Task.Delay(TimeSpan.FromSeconds(1));
        return await GetStreamAsync();
    }
}

ඔබට සුපුරුදු පරිදි මෙම ධාරාව භාවිතා කළ හැකිය:

using (var stream = await FileStreamGetter.GetStreamAsync())
{
    Console.WriteLine(stream.Length);
}

7
පුනරාවර්තනයේ සිට තොගයක් පිටවන තෙක් තත්පර කීයක් GetStreamAsync()තිබේද?
CAD bloke

ADCADbloke, ඔබ ඉතා හොඳ කරුණක් මතු කර ඇත. ගොනුවක් දීර් time කාලයක් තිස්සේ නොතිබුණහොත් ඇත්ත වශයෙන්ම මගේ නියැදියට තොග පිටාර ගැලීම් ව්‍යතිරේකයක් තිබිය හැකිය. මෙම පිළිතුරට සම්බන්ධව stackoverflow.com/questions/4513438/… , එය පැය 5 කින් ව්‍යතිරේකය ඉහළ නැංවිය හැකිය.
අයිවන් බ්‍රැනට්ස්

1
ඔබගේ භාවිත අවස්ථා හා සම්බන්ධව, ගොනුව කියවීමට ගත් උත්සාහයන් 10 ක් අසාර්ථක වී ඇතැයි කියමු නම්, I / O ව්‍යතිරේකය විසි කිරීම වඩාත් සුදුසුය. උත්සාහයන් 10 ක් අසාර්ථක වූ පසු අනෙක් උපාය තත්පරයට රැඳී සිටීමේ කාලය වැඩි කිරීම විය හැකිය. ඔබට මේ දෙකේම මිශ්‍රණයක් භාවිතා කළ හැකිය.
අයිවන් බ්‍රැනට්ස්

ගොනුව අගුළු දමා ඇති පරිශීලකයාට මම අනතුරු අඟවන්නෙමි. ඔවුන් සාමාන්‍යයෙන් එය තමන් විසින්ම අගුළු දමා ඇති නිසා ඔවුන් ඒ ගැන යමක් කරනු ඇත. නැත්ද.
CAD bloke

සමහර අවස්ථාවලදී, ගොනුවක් තවම සුදානම් නැති බැවින් ඔබ නැවත උත්සාහ කිරීමේ ප්‍රතිපත්තිය භාවිතා කළ යුතුය. කිසියම් තාවකාලික ෆෝල්ඩරයක පින්තූර බාගත කිරීම සඳහා ඩෙස්ක්ටොප් යෙදුමක් ගැන සිතන්න. යෙදුම බාගත කිරීම ආරම්භ කරන අතරම ඔබ මෙම ෆෝල්ඩරය ගොනු ගවේෂකයේ විවෘත කරයි. වින්ඩෝස් හට වහාම සිඟිති රූපයක් සාදා ගොනුව අගුළු දැමීමට අවශ්‍යය. ඒ සමඟම, ඔබගේ යෙදුම අගුළු දැමූ රූපය වෙනත් ස්ථානයකට ආදේශ කිරීමට උත්සාහ කරයි. ඔබ නැවත උත්සාහ කිරීමේ ප්‍රතිපත්තියක් භාවිතා නොකරන්නේ නම් ඔබට ව්‍යතිරේකයක් ලැබෙනු ඇත.
අයිවන් බ්‍රැනට්ස්

4

මා දන්නා එකම ක්‍රමය වන්නේ වේගවත් නොවන Win32 සුවිශේෂී අගුළු API භාවිතා කිරීමයි, නමුත් උදාහරණ තිබේ.

බොහෝ අය, මේ සඳහා සරල විසඳුමක් සඳහා, හුදෙක් ලූප උත්සාහ කිරීමට / අල්ලා ගැනීමට / නිදා ගැනීමට.


3
පළමු වරට ගොනුව විවෘත නොකර ඔබට මෙම API භාවිතා කළ නොහැක, එම අවස්ථාවේදී ඔබට තවදුරටත් අවශ්‍ය නොවේ.
හැරී ජොන්ස්ටන්

2
ෂ්‍රෝඩින්ගර්ගේ ගොනුව.
TheLastGIS

4
static bool FileInUse(string path)
    {
        try
        {
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
            {
                fs.CanWrite
            }
            return false;
        }
        catch (IOException ex)
        {
            return true;
        }
    }

string filePath = "C:\\Documents And Settings\\yourfilename";
bool isFileInUse;

isFileInUse = FileInUse(filePath);

// Then you can do some checking
if (isFileInUse)
   Console.WriteLine("File is in use");
else
   Console.WriteLine("File is not in use");

මෙය උපකාරී වේ යැයි සිතමු!


12
ඔබ සිදු කරන සත්‍ය චෙක්පත හොඳයි; එය ශ්‍රිතයක් තුළට දැමීම නොමඟ යවන සුළුය. ගොනුවක් විවෘත කිරීමට පෙර මෙවැනි ශ්‍රිතයක් භාවිතා කිරීමට ඔබට අවශ්‍ය නැත. ශ්‍රිතය තුළ, ගොනුව විවෘත කර, පරීක්ෂා කර වසා ඇත. එවිට ක්‍රමලේඛකයා ගොනුව භාවිතා කිරීමට තවමත් සුදුසු නැති අතර එය භාවිතයට විවෘත කිරීමට උත්සාහ කරයි. මෙය නරක ය, මන්ද යත් මෙම ගොනුව විවෘත කිරීම සඳහා පෝලිම් ගැසූ වෙනත් ක්‍රියාවලියක් මඟින් එය භාවිතා කර අගුළු දැමිය හැකි බැවිනි. පළමු වරට එය විවෘත කරන ලද කාලය (පරීක්ෂා කිරීම සඳහා) සහ දෙවන වරට එය විවෘත කිරීම (භාවිතය සඳහා) අතර, මෙහෙයුම් පද්ධතියට ඔබේ ක්‍රියාවලිය අවලංගු කර වෙනත් ක්‍රියාවලියක් ක්‍රියාත්මක කළ හැකිය.
ලේකි

3

ඉහත පිළිගත් පිළිතුරු ගොනුවක් බෙදාහදා ගැනීම සඳහා ගොනුවක් විවෘත කර තිබේ නම් ගැටළුවක් ඇති වේ. මෙම වෙනස් කළ විසඳුම වඩාත් විශ්වාසදායක ලෙස ක්‍රියාත්මක වන අතර මතක තබා ගත යුතු කරුණු දෙකක් ඇත (පිළිගත් විසඳුම සඳහා ද සත්‍ය වේ):

  1. ලිවීමේ කොටස් මාදිලියකින් විවෘත කර ඇති ගොනු සඳහා එය ක්‍රියා නොකරනු ඇත
  2. මෙය නූල් ගැටලු සැලකිල්ලට නොගන්නා බැවින් ඔබට එය අගුළු දැමීමට හෝ නූල් ගැටලු වෙන වෙනම හැසිරවීමට අවශ්‍ය වනු ඇත.

ඉහත කරුණු මතකයේ තබා ගනිමින්, ගොනුව ලිවීම සඳහා අගුළු දමා තිබේද නැතහොත් කියවීම වැළැක්වීම සඳහා අගුළු දමා ඇත්දැයි පරීක්ෂා කරයි :

public static bool FileLocked(string FileName)
{
    FileStream fs = null;

    try
    {
        // NOTE: This doesn't handle situations where file is opened for writing by another process but put into write shared mode, it will not throw an exception and won't show it as write locked
        fs = File.Open(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None); // If we can't open file for reading and writing then it's locked by another process for writing
    }
    catch (UnauthorizedAccessException) // https://msdn.microsoft.com/en-us/library/y973b725(v=vs.110).aspx
    {
        // This is because the file is Read-Only and we tried to open in ReadWrite mode, now try to open in Read only mode
        try
        {
            fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (Exception)
        {
            return true; // This file has been locked, we can't even open it to read
        }
    }
    catch (Exception)
    {
        return true; // This file has been locked
    }
    finally
    {
        if (fs != null)
            fs.Close();
    }
    return false;
}

පිළිගත් පිළිතුරට සමාන ගැටළුවක් තවමත් පවතී - එය ඔබට කියන්නේ එක්තරා නිශ්චිත මොහොතක වෙනත් ක්‍රියාවලියක් මඟින් ගොනුව අගුළු දමා ඇත්ද යන්න පමණක් වන අතර එය ප්‍රයෝජනවත් තොරතුරු නොවේ. ශ්‍රිතය නැවත පැමිණෙන විට ප්‍රති result ලය දැනටමත් යල්පැන ඇති විය හැකිය!
හැරී ජොන්ස්ටන්

1
එය සත්‍යයකි, කෙනෙකුට ඕනෑම වේලාවක පමණක් පරීක්ෂා කළ හැකිය (හෝ සිදුවීම් වලට දායක වන්න), පිළිගත් විසඳුමට වඩා මෙම ප්‍රවේශයේ ඇති වාසිය නම් එයට කියවීමට පමණක් ඇති ගුණාංගයක් සහ ලිවීමේ අගුලක් පරීක්ෂා කළ හැකි අතර ව්‍යාජ ධනාත්මක ප්‍රති return ල ලබා නොදේ.
rboy

3

3-ලයිනර් වැඩ කිරීම හැරුණු විට සහ යොමු කිරීම සඳහා: ඔබට සම්පූර්ණ තොරතුරු අවශ්‍ය නම් - මයික්‍රොසොෆ්ට් දේව් මධ්‍යස්ථානයේ කුඩා ව්‍යාපෘතියක් තිබේ:

https://code.msdn.microsoft.com/windowsapps/How-to-know-the-process-704839f4

හැඳින්වීමෙන්:

.NET Framework 4.0 හි සංවර්ධනය කරන ලද C # නියැදි කේතය ගොනුවක අගුලක් ඇති ක්‍රියාවලිය කුමක්දැයි සොයා ගැනීමට උපකාරී වේ. Rstrtmgr.dll හි ඇතුළත් කර ඇති RmStartSession ශ්‍රිතය නැවත ආරම්භ කිරීමේ කළමණාකරණ සැසියක් නිර්මාණය කිරීම සඳහා භාවිතා කර ඇති අතර ප්‍රතිලාභ ප්‍රති result ල අනුව Win32Exception වස්තුවෙහි නව අවස්ථාවක් නිර්මාණය වේ. RmRegisterRescources ශ්‍රිතය හරහා සම්පත් නැවත ආරම්භ කිරීමේ කළමණාකරණ සැසියකට ලියාපදිංචි කිරීමෙන් පසුව , RM_PROCESS_INFO අරාව ගණනය කිරීමෙන් විශේෂිත ගොනුවක් භාවිතා කරන යෙදුම් මොනවාදැයි පරීක්ෂා කිරීමට RmGetList ශ්‍රිතය කැඳවනු ලැබේ.

එය "නැවත ආරම්භ කිරීමේ කළමනාකරු සැසිය" වෙත සම්බන්ධ වීමෙන් ක්‍රියා කරයි.

නැවත ආරම්භ කිරීමේ කළමනාකරු සැසිය සමඟ ලියාපදිංචි වී ඇති සම්පත් ලැයිස්තුව භාවිතා කරන්නේ කුමන යෙදුම් සහ සේවාවන් වසා දමා නැවත ආරම්භ කළ යුතුද යන්න තීරණය කිරීම සඳහා ය. ගොනු යෙදුම් , සේවා කෙටි නම් හෝ ධාවනය වන යෙදුම් විස්තර කරන RM_UNIQUE_PROCESS ව්‍යුහයන් මගින් සම්පත් හඳුනාගත හැකිය .

එය ඔබගේ විශේෂ අවශ්‍යතා සඳහා මදක් අධිෂ් ed ාන සහගත විය හැකිය ... නමුත් ඔබට අවශ්‍ය වන්නේ එය නම්, ඉදිරියට ගොස් එදිරිව ව්‍යාපෘතිය අල්ලා ගන්න.


3

මට වරක් ඔන්ලයින් උපස්ථ ලේඛනාගාරයකට PDF උඩුගත කිරීමට අවශ්‍ය විය. පරිශීලකයා වෙනත් වැඩසටහනක (PDF කියවනය වැනි) ගොනුව විවෘත කර ඇත්නම් උපස්ථය අසාර්ථක වේ. මගේ කඩිමුඩියේ, මම මෙම ත්‍රෙඩ් එකේ ඉහළම පිළිතුරු කිහිපයක් උත්සාහ කළ නමුත් ඒවා ක්‍රියාත්මක කිරීමට නොහැකි විය. මට වැඩ කළේ පී.ඩී.එෆ් ගොනුව එහි නාමාවලිය වෙත ගෙන යාමට උත්සාහ කිරීමයි . වෙනත් වැඩසටහනක ගොනුව විවෘතව පැවතුනහොත් මෙය අසාර්ථක වන බව මට පෙනී ගිය අතර, එම පියවර සාර්ථක වුවහොත් එය වෙනම නාමාවලියකට ගෙන ගියහොත් නැවත පිහිටුවීමේ ක්‍රියාවලියක් අවශ්‍ය නොවේ. මගේ මූලික විසඳුම අන් අයගේ විශේෂිත භාවිත අවස්ථා සඳහා ප්‍රයෝජනවත් විය හැකි අවස්ථාවක පළ කිරීමට මට අවශ්‍යය.

string str_path_and_name = str_path + '\\' + str_filename;
FileInfo fInfo = new FileInfo(str_path_and_name);
bool open_elsewhere = false;
try
{
    fInfo.MoveTo(str_path_and_name);
}
catch (Exception ex)
{
    open_elsewhere = true;
}

if (open_elsewhere)
{
    //handle case
}

2

මගේ අත්දැකීම් අනුව, ඔබට සාමාන්‍යයෙන් මෙය කිරීමට අවශ්‍යය, ඉන්පසු ඔබේ ලිපිගොනු මනස්කාන්ත දෙයක් කිරීමට 'ආරක්‍ෂා' කර 'ආරක්‍ෂිත' ගොනු භාවිතා කරන්න. ඔබට මේ ආකාරයට භාවිතා කිරීමට අවශ්‍ය එක් ගොනුවක් පමණක් තිබේ නම්, ඔබට පිළිතුරෙහි පැහැදිලි කර ඇති උපක්‍රමය ජෙරමි තොම්සන් විසින් භාවිතා කළ හැකිය. කෙසේ වෙතත්, ඔබ මෙය බොහෝ ලිපිගොනු මත කිරීමට උත්සාහ කරන්නේ නම් (උදාහරණයක් ලෙස, ඔබ ස්ථාපකයෙකු ලියන විට), ඔබ සිටින්නේ තරමක් රිදවීමට ය.

මෙය විසඳිය හැකි ඉතා අලංකාර ක්‍රමයක් නම්, එහි ගොනු වලින් එකක් භාවිතා කරන්නේ නම් ෆෝල්ඩරයේ නමක් වෙනස් කිරීමට ඔබේ ගොනු පද්ධතිය ඔබට ඉඩ නොදෙන බැවිනි. ෆෝල්ඩරය එකම ගොනු පද්ධතියක් තුළ තබා ගන්න, එය චාම් එකක් මෙන් ක්‍රියා කරයි.

මෙය ගසාකෑමට හැකි පැහැදිලි ක්‍රම පිළිබඳව ඔබ දැනුවත් විය යුතු බව සලකන්න. සියල්ලට පසු, ගොනු අගුළු නොදමනු ඇත. එසේම, ඔබේ Moveමෙහෙයුම අසාර්ථක වීමට හේතු විය හැකි වෙනත් හේතු ඇති බව මතක තබා ගන්න . නිසැකවම නිසි දෝෂ හැසිරවීම (MSDN) මෙතැනින් උපකාරී වේ.

var originalFolder = @"c:\myHugeCollectionOfFiles"; // your folder name here
var someFolder = Path.Combine(originalFolder, "..", Guid.NewGuid().ToString("N"));

try
{
    Directory.Move(originalFolder, someFolder);

    // Use files
}
catch // TODO: proper exception handling
{
    // Inform user, take action
}
finally
{
    Directory.Move(someFolder, originalFolder);
}

තනි ලිපිගොනු සඳහා මම ජෙරමි තොම්සන් විසින් පළ කරන ලද අගුලු දැමීමේ යෝජනාවට එකඟ වෙමි.


හායි, පිළිතුරු වෙනස්කම් අනුපිළිවෙල සිට ඔබ පශ්චාත් පැහැදිලි කළ හැකි ඉහත මෙම මහජන QA පාඨකයන්ට සඳහා අදහස් ඔබ. ස්තූතියි.
ජෙරමි තොම්සන්

1
@ ජෙරමි තොම්සන් ඔබ හරි, ස්තූතියි, මම ලිපිය සංස්කරණය කරමි. මම ඔබෙන් විසඳුම භාවිතා කරමි, ප්‍රධාන වශයෙන් ඔබ නිවැරදිව භාවිතා කිරීම FileShareසහ අගුලක් පරීක්ෂා කිරීම නිසාය.
atlaste

2

මෙන්න මට හොඳට කිව හැකි තාක් දුරට පිළිගත් පිළිතුරට සමාන නමුත් අඩු කේතයක් සහිත කේතයක් ඇත:

    public static bool IsFileLocked(string file)
    {
        try
        {
            using (var stream = File.OpenRead(file))
                return false;
        }
        catch (IOException)
        {
            return true;
        }        
    }

කෙසේ වෙතත් එය පහත දැක්වෙන ආකාරයට කිරීම වඩා ශක්තිමත් යැයි මම සිතමි:

    public static void TryToDoWithFileStream(string file, Action<FileStream> action, 
        int count, int msecTimeOut)
    {
        FileStream stream = null;
        for (var i = 0; i < count; ++i)
        {
            try
            {
                stream = File.OpenRead(file);
                break;
            }
            catch (IOException)
            {
                Thread.Sleep(msecTimeOut);
            }
        }
        action(stream);
    }

2

බහු යෙදුම් වලින් ලිපිගොනු වෙත ප්‍රවේශ වීම සඳහා ඔබට මගේ පුස්තකාලය භාවිතා කළ හැකිය.

ඔබට එය නුගට් වෙතින් ස්ථාපනය කළ හැකිය: ස්ථාපනය-පැකේජය Xabe.FileLock

ඔබට ඒ පිළිබඳ වැඩි විස්තර අවශ්‍ය නම් https://github.com/tomaszzmuda/Xabe.FileLock පරීක්ෂා කරන්න

ILock fileLock = new FileLock(file);
if(fileLock.Acquire(TimeSpan.FromSeconds(15), true))
{
    using(fileLock)
    {
        // file operations here
    }
}

fileLock.Acquire ක්‍රමය සත්‍ය වන්නේ මෙම වස්තුව සඳහා පමණක් ගොනුව අගුළු දැමිය හැකි නම් පමණි. නමුත් ගොනුව උඩුගත කරන යෙදුම එය ගොනු අගුලෙහිද කළ යුතුය. වස්තුව ප්‍රවේශ කළ නොහැකි නම් පාරදෘශ්‍යය වැරදිය.


1
කරුණාකර පිළිතුරක් ලෙස කිසියම් මෙවලමක් හෝ පුස්තකාලයක් පළ නොකරන්න. අවම වශයෙන් එය පිළිතුරෙන්ම ගැටලුව විසඳන ආකාරය නිරූපණය කරන්න .
paper1111

එකතු කළ නිරූපණය :) සමාවෙන්න @ paper1111
ටොමාස් um මුඩා

2
සහයෝගයෙන් කටයුතු කිරීමට ගොනුව භාවිතා කරන සියලුම ක්‍රියාදාමයන් අවශ්‍ය වේ. OPs මුල් ගැටළුවට අදාළ විය නොහැක.
හැරී ජොන්ස්ටන්

0

මෙය කිසියම් WTF ප්‍රතීකයක් අවුලුවන්නේ දැයි බැලීමට මම කැමැත්තෙමි. කොන්සෝල යෙදුමකින් PDF ලේඛනයක් නිර්මාණය කර පසුව දියත් කරන ක්‍රියාවලියක් මා සතුව ඇත. කෙසේ වෙතත්, මම ගනුදෙනු කළේ බොහෝ විට පරිශීලකයා විසින් ක්‍රියාවලිය කිහිප වතාවක් ක්‍රියාත්මක කළහොත්, කලින් ජනනය කරන ලද ගොනුව වසා නොගෙන එකම ගොනුවක් ජනනය කරන්නේ නම්, යෙදුම ව්‍යතිරේකයක් විසි කර මිය යනු ඇත. ගොනු නාම පදනම් වී ඇත්තේ විකුණුම් මිල ගණන් මත වන නිසා මෙය නිතර නිතර සිදුවීමකි.

එබඳු අගෞරවනීය ආකාරයකින් අසමත් වෙනවා වෙනුවට, ස්වයංක්‍රීයව වැඩි කරන ලද ගොනු අනුවාදය මත විශ්වාසය තැබීමට මම තීරණය කළෙමි:

private static string WriteFileToDisk(byte[] data, string fileName, int version = 0)
{
    try
    {
        var versionExtension = version > 0 ? $"_{version:000}" : string.Empty;
        var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{fileName}{versionExtension}.pdf");
        using (var writer = new FileStream(filePath, FileMode.Create))
        {
            writer.Write(data, 0, data.Length);
        }
        return filePath;
    }
    catch (IOException)
    {
        return WriteFileToDisk(data, fileName, ++version);
    }
}

catchමම නිවැරදි IOException (ය) අල්ලාගෙන සිටින බව සහතික කිරීම සඳහා වාරණයට තවත් සැලකිලිමත් විය හැකිය . මෙම ලිපිගොනු කෙසේ හෝ තාවකාලික වීමට අදහස් කරන බැවින් මම ආරම්භයේ දී යෙදුම් ආචයනය ඉවත් කරමි.

ගොනුව භාවිතයේ තිබේදැයි පරීක්ෂා කිරීම පිළිබඳ OP හි ප්‍රශ්නයේ සීමාවෙන් ඔබ්බට ගිය බව මට වැටහී ඇති නමුත් ඇත්ත වශයෙන්ම මා මෙහි පැමිණි විට විසඳීමට බලාපොරොත්තු වූ ගැටලුව මෙය බැවින් එය වෙනත් කෙනෙකුට ප්‍රයෝජනවත් වනු ඇත.


0

මේ වගේ දෙයක් උදව් වෙයිද?

var fileWasWrittenSuccessfully = false;
while (fileWasWrittenSuccessfully == false)
{
    try
    {
        lock (new Object())
        {
            using (StreamWriter streamWriter = new StreamWriter(filepath.txt"), true))
            {
                streamWriter.WriteLine("text");
            }
        }

        fileWasWrittenSuccessfully = true;
    }
    catch (Exception)
    {

    }
}

0
retry_possibility:
//somecode here

try
{
    using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
    {
        stream.Close();
    }
    //write or open your file here
}
catch (IOException)
{
    DialogResult dialogResult = MessageBox.Show("This file is opened by you or another user. Please close it and press retry.\n"+ expFilePath, "File Locked", MessageBoxButtons.RetryCancel);
    if (dialogResult == DialogResult.Retry)
    {
        goto retry_possibility;
    }
    else if (dialogResult == DialogResult.Cancel)
    {
        //do nothing
    }
}

-2

උත්සාහ කර ගොනුව තාවකාලික ඩිර් වෙත ගෙනයන්න / පිටපත් කරන්න. ඔබට හැකි නම්, එයට අගුලක් නොමැති අතර ඔබට අගුල් ලබා නොගෙන තාවකාලිකව වැඩ කළ හැකිය. නැතහොත් තත්පර x කින් එය නැවත ගෙනයාමට උත්සාහ කරන්න.


@jcolebrand අගුලු දමන්නේ කුමක් ද? ඔබ පිටපත් කළ එක? නැත්නම් ඔබ තාවකාලිකව තැබූ කෙනාද?
Cullub

5
ඔබ ගොනුව පිටපත් කරන්නේ නම්, වෙනත් කිසිවෙකු එය ක්‍රියාත්මක නොකරනු ඇතැයි අපේක්ෂා කරමින්, ඔබ තාවකාලික ගොනුව භාවිතා කිරීමට යන්නේ නම්, ඔබ එය පිටපත් කළ වහාම යමෙකු එය අගුළු දැමුවහොත් ඔබට දත්ත අහිමි විය හැකිය.
jcolebrand

-3

මම මෙම ක්‍රියාකාරීත්වය භාවිතා කරමි, නමුත් මම IsFileLocked ශ්‍රිතය සමඟ ගොනු අගුලු දැමීම පරීක්ෂා කරන විට සහ ගොනුව විවෘත කරන විට කාල පරාසයක් ඇත. මෙම කාල පරාසය තුළ වෙනත් නූලකට ගොනුව විවෘත කළ හැකිය, එබැවින් මට IOException ලැබෙනු ඇත.

ඉතින්, මම මේ සඳහා අමතර කේතයක් එකතු කළා. මගේ නඩුවේදී මට XDocument පැටවීමට අවශ්‍යයි:

        XDocument xDoc = null;

        while (xDoc == null)
        {
            while (IsFileBeingUsed(_interactionXMLPath))
            {
                Logger.WriteMessage(Logger.LogPrioritet.Warning, "Deserialize can not open XML file. is being used by another process. wait...");
                Thread.Sleep(100);
            }
            try
            {
                xDoc = XDocument.Load(_interactionXMLPath);
            }
            catch
            {
                Logger.WriteMessage(Logger.LogPrioritet.Error, "Load working!!!!!");
            }
        }

ඔයා සිතන්නේ කුමක් ද? මට යමක් වෙනස් කළ හැකිද? සමහර විට මට IsFileBeingUsed ශ්‍රිතය භාවිතා කිරීමට අවශ්‍ය නොවීය.

ස්තූතියි


5
IsFileBeingUsed යනු කුමක්ද? IsFileBeingUsed පිළිබඳ ප්‍රභව කේතය?
කික්නෙට්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.