GapBuffer<char> buf = new GapBuffer<char>();
const int MaxSemaphoreCount = 1;
SemaphoreSlim Semaphore = new SemaphoreSlim(MaxSemaphoreCount);
+ ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();
public StringBuffer()
{
}
}
- /// <summary>
- /// ロックを解除します
- /// </summary>
- public void UnLock()
- {
- this.Semaphore.Release();
- }
-
- /// <summary>
- /// ロックします
- /// </summary>
- public void Lock()
- {
- this.Semaphore.Wait();
- }
-
- /// <summary>
- /// ロックします
- /// </summary>
- /// <returns>Taskオブジェクト</returns>
- public Task LockAsync()
- {
- return this.Semaphore.WaitAsync();
- }
-
public StringBuffer(StringBuffer buffer)
: this()
{
public string ToString(int index, int length)
{
- this.Lock();
+ this.rwlock.EnterReadLock();
StringBuilder temp = new StringBuilder();
temp.Clear();
for (int i = index; i < index + length; i++)
temp.Append(buf[i]);
- this.UnLock();
+ this.rwlock.ExitReadLock();
return temp.ToString();
}
internal void Replace(GapBuffer<char> buf)
{
- this.Lock();
+ this.rwlock.EnterWriteLock();
this.Clear();
this.buf = buf;
- this.UnLock();
+ this.rwlock.ExitWriteLock();
this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, 0, 0, buf.Count));
}
internal void Replace(int index, int length, IEnumerable<char> chars,int count)
{
- this.Lock();
+ this.rwlock.EnterWriteLock();
try{
if (length > 0)
}
finally
{
- this.UnLock();
+ this.rwlock.ExitWriteLock();
}
this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, index, length, count));
//内部形式に変換する
var internal_str = from s in str where s != '\r' && s != '\0' select s;
- await this.LockAsync().ConfigureAwait(false);
+ this.rwlock.EnterWriteLock();
//str.lengthは事前に確保しておくために使用するので影響はない
this.buf.InsertRange(index, internal_str, str.Length);
- this.UnLock();
+ this.rwlock.ExitWriteLock();
if (tokenSource != null)
tokenSource.Token.ThrowIfCancellationRequested();
} while (readCount > 0);
}
+ internal async Task SaveAsync(TextWriter fs,CancellationTokenSource tokenSource=null)
+ {
+ try
+ {
+ this.rwlock.EnterWriteLock();
+ StringBuilder line = new StringBuilder();
+ for (int i = 0; i < this.Length; i++)
+ {
+ char c = this[i];
+ line.Append(c);
+ if (c == Document.NewLine || i == this.Length - 1)
+ {
+ string str = line.ToString();
+ str = str.Replace(Document.NewLine.ToString(), fs.NewLine);
+ await fs.WriteAsync(str).ConfigureAwait(false);
+ line.Clear();
+ if (tokenSource != null)
+ tokenSource.Token.ThrowIfCancellationRequested();
+#if TEST_ASYNC
+ System.Threading.Thread.Sleep(10);
+#endif
+ }
+ }
+ }
+ finally
+ {
+ this.rwlock.ExitWriteLock();
+ }
+ }
+
internal void ReplaceRegexAll(LineToIndexTable layoutlines, Regex regex, string pattern, bool groupReplace)
{
for (int i = 0; i < layoutlines.Count; i++)
return pattern;
});
- this.Lock();
+ this.rwlock.EnterWriteLock();
try
{
//空行は削除する必要はない
}
finally
{
- this.UnLock();
+ this.rwlock.ExitWriteLock();
}
this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, lineHeadIndex, lineLength, output.Length, i));
int newLineLength = lineLength;
while ((right = ts.IndexOf(this.buf, left, lineHeadIndex + newLineLength)) != -1)
{
- this.Lock();
+ this.rwlock.EnterWriteLock();
try
{
this.buf.RemoveRange(right, target.Length);
}
finally
{
- this.UnLock();
+ this.rwlock.ExitWriteLock();
}
left = right + pattern.Length;
internal int IndexOf(string target, int start,bool ci = false)
{
- this.Lock();
+ this.rwlock.EnterReadLock();
TextSearch ts = new TextSearch(target,ci);
int patternIndex = ts.IndexOf(this.buf, start,this.buf.Count);
- this.UnLock();
+ this.rwlock.ExitReadLock();
return patternIndex;
}