Skip to content

Commit c0996be

Browse files
committed
Various refactorings.
1 parent 3077837 commit c0996be

10 files changed

+517
-207
lines changed

App.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
1212
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
1313
</dependentAssembly>
14+
<dependentAssembly>
15+
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
16+
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
17+
</dependentAssembly>
1418
</assemblyBinding>
1519
</runtime>
1620
</configuration>

AsyncToSyncCodeRoundtripSynchroniserMonitorNet.csproj

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
<DefineConstants>DEBUG;TRACE</DefineConstants>
2424
<ErrorReport>prompt</ErrorReport>
2525
<WarningLevel>4</WarningLevel>
26-
<NoWarn>SEC0122;S125;S1125;S1135;S1199;S2589;S3881;S3358;S4136;S4457;CA1034;CA1063;CCN0011;CCN0021;CCN0031;1701;1702;AsyncFixed01;MS002;MS003;IDE0018;AD0001;SEC0112</NoWarn>
27-
<WarningsAsErrors>NU1605</WarningsAsErrors>
26+
<NoWarn>CS1998;SEC0122;S125;S1125;S1135;S1199;S2589;S3881;S3358;S4136;S4457;CA1034;CA1063;CCN0011;CCN0021;CCN0031;1701;1702;AsyncFixed01;MS002;MS003;IDE0018;AD0001;SEC0112</NoWarn>
27+
<WarningsAsErrors>CS4014;NU1605</WarningsAsErrors>
2828
</PropertyGroup>
2929
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
3030
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -34,8 +34,8 @@
3434
<DefineConstants>TRACE</DefineConstants>
3535
<ErrorReport>prompt</ErrorReport>
3636
<WarningLevel>4</WarningLevel>
37-
<NoWarn>SEC0122;S125;S1125;S1135;S1199;S2589;S3881;S3358;S4136;S4457;CA1034;CA1063;CCN0011;CCN0021;CCN0031;1701;1702;AsyncFixed01;MS002;MS003;IDE0018;AD0001;SEC0112</NoWarn>
38-
<WarningsAsErrors>NU1605</WarningsAsErrors>
37+
<NoWarn>CS1998;SEC0122;S125;S1125;S1135;S1199;S2589;S3881;S3358;S4136;S4457;CA1034;CA1063;CCN0011;CCN0021;CCN0031;1701;1702;AsyncFixed01;MS002;MS003;IDE0018;AD0001;SEC0112</NoWarn>
38+
<WarningsAsErrors>CS4014;NU1605</WarningsAsErrors>
3939
<DebugSymbols>true</DebugSymbols>
4040
</PropertyGroup>
4141
<PropertyGroup>
@@ -45,6 +45,9 @@
4545
<ApplicationManifest>app.manifest</ApplicationManifest>
4646
</PropertyGroup>
4747
<ItemGroup>
48+
<Reference Include="AsyncEnumerable, Version=4.0.2.0, Culture=neutral, PublicKeyToken=0426b068161bd1d1, processorArchitecture=MSIL">
49+
<HintPath>..\..\FolderSync\FolderSyncNet\packages\AsyncEnumerator.4.0.2\lib\net45\AsyncEnumerable.dll</HintPath>
50+
</Reference>
4851
<Reference Include="Microsoft.Extensions.Configuration, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
4952
<HintPath>packages\Microsoft.Extensions.Configuration.1.1.2\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll</HintPath>
5053
</Reference>
@@ -133,8 +136,8 @@
133136
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
134137
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
135138
</Reference>
136-
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
137-
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.3.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
139+
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
140+
<HintPath>..\..\FolderSync\FolderSyncNet\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
138141
</Reference>
139142
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
140143
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
@@ -151,6 +154,9 @@
151154
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
152155
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
153156
</Reference>
157+
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
158+
<HintPath>..\..\FolderSync\FolderSyncNet\packages\System.Threading.Tasks.Extensions.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll</HintPath>
159+
</Reference>
154160
<Reference Include="System.Windows.Forms" />
155161
<Reference Include="System.IO.Compression.FileSystem" />
156162
<Reference Include="System.Numerics" />

AsyncToSyncConverter.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define ASYNC
1010
using System;
1111
using System.Collections.Generic;
12+
using System.IO;
1213
using System.Text.RegularExpressions;
1314
using System.Threading.Tasks;
1415

@@ -120,15 +121,15 @@ static class AsyncToSyncConverter
120121

121122

122123

123-
public static async Task AsyncFileUpdated(string fullName, Context context)
124+
public static async Task AsyncFileUpdated(Context context)
124125
{
125126
//using (await Global.FileOperationAsyncLock.LockAsync())
126127
{
127-
var fileData = await FileExtensions.ReadAllTextAsync(Extensions.GetLongPath(fullName), context.Token);
128+
var fileData = await FileExtensions.ReadAllTextAsync(Extensions.GetLongPath(context.Event.FullName), context.Token);
128129
var originalData = fileData;
129130

130131

131-
if (fullName.EndsWith(".cs"))
132+
if (context.Event.FullName.EndsWith(".cs"))
132133
{
133134
foreach (var replacement in CS_Replacements)
134135
{
@@ -140,7 +141,7 @@ public static async Task AsyncFileUpdated(string fullName, Context context)
140141
fileData = CS_TaskReplaceRegex.Replace(fileData, CS_TaskReplaceRegexReplacement);
141142
fileData = CS_TaskDelayReplaceRegex.Replace(fileData, CS_TaskDelayReplaceRegexReplacement);
142143
}
143-
else if (fullName.EndsWith(".py"))
144+
else if (context.Event.FullName.EndsWith(".py"))
144145
{
145146
foreach (var replacement in PY_Replacements)
146147
{
@@ -156,7 +157,7 @@ public static async Task AsyncFileUpdated(string fullName, Context context)
156157
}
157158

158159

159-
await ConsoleWatch.SaveFileModifications(fullName, fileData, originalData, context);
160+
await ConsoleWatch.SaveFileModifications(fileData, originalData, context);
160161

161162
} //using (await Global.FileOperationAsyncLock.LockAsync())
162163
} //public static async Task AsyncFileUpdated(string fullName, Context context)

BinaryFileExtensions.cs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,24 @@ namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
1717
{
1818
public static partial class FileExtensions
1919
{
20+
public static int MaxByteArraySize = 0x7FFFFFC7; //https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element?redirectedfrom=MSDN#remarks
21+
2022
//https://stackoverflow.com/questions/18472867/checking-equality-for-two-byte-arrays/
2123
public static bool BinaryEqual(Binary a, Binary b)
2224
{
2325
return a.Equals(b);
2426
}
2527

26-
public static async Task<byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
28+
public static async Task<Tuple<byte[], long>> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default(CancellationToken), long maxFileSize = 0)
2729
{
2830
while (true)
2931
{
3032
if (cancellationToken.IsCancellationRequested)
31-
return await Task.FromCanceled<byte[]>(cancellationToken);
33+
return await Task.FromCanceled<Tuple<byte[], long>>(cancellationToken);
3234

3335
try
3436
{
35-
using (FileStream stream = new FileStream(
37+
using (var stream = new FileStream(
3638
path,
3739
FileMode.Open,
3840
FileAccess.Read,
@@ -41,10 +43,17 @@ public static bool BinaryEqual(Binary a, Binary b)
4143
useAsync: true
4244
))
4345
{
44-
var len = (int)stream.Length; //NB! the lenght might change during the code execution, so need to save it into separate variable
46+
long len = stream.Length; //NB! the length might change during the code execution, so need to save it into separate variable
47+
48+
maxFileSize = Math.Min(MaxByteArraySize, maxFileSize);
49+
if (maxFileSize > 0 && len > maxFileSize)
50+
{
51+
return new Tuple<byte[], long>(null, len);
52+
}
53+
4554
byte[] result = new byte[len];
46-
await stream.ReadAsync(result, 0, len, cancellationToken);
47-
return result;
55+
await stream.ReadAsync(result, 0, (int)len, cancellationToken);
56+
return new Tuple<byte[], long>(result, len);
4857
}
4958
}
5059
catch (IOException)
@@ -61,21 +70,21 @@ public static bool BinaryEqual(Binary a, Binary b)
6170
catch (TaskCanceledException)
6271
{
6372
//do nothing here
64-
return await Task.FromCanceled<byte[]>(cancellationToken);
73+
return await Task.FromCanceled<Tuple<byte[], long>>(cancellationToken);
6574
}
6675
}
6776
}
6877
}
6978

70-
public static async Task WriteAllBytesAsync(string path, byte[] contents, CancellationToken cancellationToken = default(CancellationToken))
79+
public static async Task WriteAllBytesAsync(string path, byte[] contents, CancellationToken cancellationToken = default(CancellationToken), int writeBufferKB = 0, int bufferWriteDelayMs = 0)
7180
{
7281
while (true)
7382
{
7483
cancellationToken.ThrowIfCancellationRequested();
7584

7685
try
7786
{
78-
using (FileStream stream = new FileStream(
87+
using (var stream = new FileStream(
7988
path,
8089
FileMode.OpenOrCreate,
8190
FileAccess.Write,
@@ -84,7 +93,24 @@ public static bool BinaryEqual(Binary a, Binary b)
8493
useAsync: true
8594
))
8695
{
87-
await stream.WriteAsync(contents, 0, contents.Length, cancellationToken);
96+
var writeBufferLength = writeBufferKB * 1024;
97+
if (writeBufferLength <= 0 || bufferWriteDelayMs <= 0) //NB! disable write buffer length limit if delay is 0
98+
writeBufferLength = contents.Length;
99+
100+
for (int i = 0; i < contents.Length; i += writeBufferLength)
101+
{
102+
if (i > 0 && bufferWriteDelayMs > 0)
103+
{
104+
#if !NOASYNC
105+
await Task.Delay(bufferWriteDelayMs, cancellationToken);
106+
#else
107+
cancellationToken.WaitHandle.WaitOne(bufferWriteDelayMs);
108+
#endif
109+
}
110+
111+
await stream.WriteAsync(contents, i, writeBufferLength, cancellationToken);
112+
}
113+
88114
return;
89115
}
90116
}

Extensions.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#define ASYNC
1010
using System;
1111
using System.Collections.Generic;
12+
using System.IO;
13+
using System.Threading;
14+
using System.Threading.Tasks;
15+
using Nito.AsyncEx;
1216

1317
namespace AsyncToSyncCodeRoundtripSynchroniserMonitor
1418
{
@@ -46,6 +50,29 @@ public static Dictionary<TValue, TKey> Inverse<TKey, TValue>(this IDictionary<TK
4650
return result;
4751
}
4852

53+
public static long? CheckDiskSpace(string path)
54+
{
55+
long? freeBytes = null;
56+
57+
try //NB! on some drives (for example, RAM drives, GetDiskFreeSpaceEx does not work
58+
{
59+
//NB! DriveInfo works on paths well in Linux //TODO: what about Mac?
60+
var drive = new DriveInfo(path);
61+
freeBytes = drive.AvailableFreeSpace;
62+
}
63+
catch (ArgumentException)
64+
{
65+
if (ConfigParser.IsWindows)
66+
{
67+
long freeBytesOut;
68+
if (WindowsDllImport.GetDiskFreeSpaceEx(path, out freeBytesOut, out var _, out var __))
69+
freeBytes = freeBytesOut;
70+
}
71+
}
72+
73+
return freeBytes;
74+
}
75+
4976
public static string GetLongPath(string path)
5077
{
5178
//@"\\?\" prefix is needed for reading from long paths: https://stackoverflow.com/questions/44888844/directorynotfoundexception-when-using-long-paths-in-net-4-7 and https://superuser.com/questions/1617012/support-of-the-unc-server-share-syntax-in-windows
@@ -59,5 +86,18 @@ public static string GetLongPath(string path)
5986
return @"\\?\" + path;
6087
}
6188
}
89+
90+
public static async Task FSOperation(Action func, CancellationToken token)
91+
{
92+
//await Task.Run(func).WaitAsync(token);
93+
func();
94+
}
95+
96+
public static async Task<T> FSOperation<T>(Func<T> func, CancellationToken token)
97+
{
98+
//var result = await Task.Run(func).WaitAsync(token);
99+
var result = func();
100+
return result;
101+
}
62102
}
63103
}

0 commit comments

Comments
 (0)