Skip to content

Commit c687e8d

Browse files
committed
Added timeout for Directory.Exists on Windows because it can stall the main thread for 15-30 seconds for unreachable network drives if no timeout is defined
1 parent 9bc2196 commit c687e8d

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

Plugins/SimpleFileBrowser/Scripts/FileBrowser.cs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using UnityEngine;
1+
//#define WIN_DIR_CHECK_WITHOUT_TIMEOUT // When uncommented, Directory.Exists won't be wrapped inside a Task/Thread on Windows but we won't be able to set a timeout for unreachable directories/drives
2+
3+
using UnityEngine;
24
using UnityEngine.EventSystems;
35
using UnityEngine.UI;
46
using System;
@@ -541,6 +543,10 @@ private static FileBrowser Instance
541543
#endif
542544
private int numberOfDriveQuickLinks;
543545

546+
#if !WIN_DIR_CHECK_WITHOUT_TIMEOUT && ( UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN )
547+
private readonly List<string> timedOutDirectoryExistsRequests = new List<string>( 2 );
548+
#endif
549+
544550
private bool canvasDimensionsChanged;
545551

546552
private readonly CompareInfo textComparer = new CultureInfo( "en-US" ).CompareInfo;
@@ -1058,6 +1064,11 @@ private void RefreshDriveQuickLinks()
10581064
bool drivesListHasntChanged = true;
10591065
for( int i = 0; i < drives.Length; i++ )
10601066
{
1067+
#if !WIN_DIR_CHECK_WITHOUT_TIMEOUT && ( UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN )
1068+
if( timedOutDirectoryExistsRequests.Contains( drives[i] ) )
1069+
continue;
1070+
#endif
1071+
10611072
if( drives[i] != driveQuickLinks[i] )
10621073
{
10631074
drivesListHasntChanged = false;
@@ -1175,10 +1186,10 @@ private void RefreshDriveQuickLinks()
11751186
// Verify that current directory still exists
11761187
try
11771188
{
1178-
if( !string.IsNullOrEmpty( m_currentPath ) && !Directory.Exists( m_currentPath ) )
1189+
if( !string.IsNullOrEmpty( m_currentPath ) && !FileBrowserHelpers.DirectoryExists( m_currentPath ) )
11791190
{
11801191
string currentPathRoot = Path.GetPathRoot( m_currentPath );
1181-
if( !string.IsNullOrEmpty( currentPathRoot ) && Directory.Exists( currentPathRoot ) )
1192+
if( !string.IsNullOrEmpty( currentPathRoot ) && FileBrowserHelpers.DirectoryExists( currentPathRoot ) )
11821193
CurrentPath = currentPathRoot;
11831194
else if( allQuickLinks.Count > 0 )
11841195
CurrentPath = allQuickLinks[0].TargetPath;
@@ -2220,7 +2231,11 @@ private bool AddQuickLink( Sprite icon, string name, string path )
22202231
if( !FileBrowserHelpers.ShouldUseSAFForPath( path ) )
22212232
#endif
22222233
{
2234+
#if !WIN_DIR_CHECK_WITHOUT_TIMEOUT && ( UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN )
2235+
if( !CheckDirectoryExistsWithTimeout( path ) )
2236+
#else
22232237
if( !Directory.Exists( path ) )
2238+
#endif
22242239
return false;
22252240

22262241
path = GetPathWithoutTrailingDirectorySeparator( path.Trim() );
@@ -2623,6 +2638,42 @@ private string GetInitialPath( string initialPath )
26232638

26242639
return initialPath;
26252640
}
2641+
2642+
#if !WIN_DIR_CHECK_WITHOUT_TIMEOUT && ( UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN )
2643+
private bool CheckDirectoryExistsWithTimeout( string path, int timeout = 750 )
2644+
{
2645+
if( timedOutDirectoryExistsRequests.Contains( path ) )
2646+
return false;
2647+
2648+
// Directory.Exists freezes for ~15 seconds for unreachable network drives on Windows, set a timeout using threads
2649+
bool directoryExists = false;
2650+
try
2651+
{
2652+
#if NET_STANDARD_2_0 || NET_4_6
2653+
// Credit: https://stackoverflow.com/a/52661569/2373034
2654+
System.Threading.Tasks.Task task = new System.Threading.Tasks.Task( () => directoryExists = Directory.Exists( path ) );
2655+
task.Start();
2656+
if( !task.Wait( timeout ) )
2657+
timedOutDirectoryExistsRequests.Add( path );
2658+
#else
2659+
// Credit: https://stackoverflow.com/q/1232953/2373034
2660+
System.Threading.Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( () => directoryExists = Directory.Exists( path ) ) );
2661+
thread.Start();
2662+
if( !thread.Join( timeout ) )
2663+
{
2664+
timedOutDirectoryExistsRequests.Add( path );
2665+
thread.Abort();
2666+
}
2667+
#endif
2668+
}
2669+
catch
2670+
{
2671+
directoryExists = Directory.Exists( path );
2672+
}
2673+
2674+
return directoryExists;
2675+
}
2676+
#endif
26262677
#endregion
26272678

26282679
#region File Browser Functions (static)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.yasirkula.simplefilebrowser",
33
"displayName": "Simple File Browser",
4-
"version": "1.5.2",
4+
"version": "1.5.3",
55
"documentationUrl": "https://github.com/yasirkula/UnitySimpleFileBrowser",
66
"changelogUrl": "https://github.com/yasirkula/UnitySimpleFileBrowser/releases",
77
"licensesUrl": "https://github.com/yasirkula/UnitySimpleFileBrowser/blob/master/LICENSE.txt",

0 commit comments

Comments
 (0)