私はあなたのようにそれを設定した場合SemaphoreSlimは一度に1つのスレッドで実行されるコードのセクションを制限することを示しているSemaphoreSlim SemaphoreSlim MSDN のためのドキュメント読んでいる:しかし、それはdoesnのSemaphoreSlim(.NET)は、同じスレッドがブロックに入ることを防止しますか?
SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
をt 同じスレッドがそのコードにアクセスするのを停止するかどうかを示します。これは非同期であり、待ち受けています。あるメソッドでawaitを使用すると、コントロールはそのメソッドを終了し、完了したタスクまたはスレッドがあれば返します。私の例では、非同期ボタンハンドラを持つボタンを使用します。それは 'await'で別のメソッド(Function1)を呼び出します。 Function1が順番に呼び出す
await Task.Run(() => Function2(beginCounter));
私の周りにTask.Run()私はSemaphoreSlimを持っています。それは、同じスレッドがFunction2に到達するのを止めるように思えます。しかし、これはドキュメントから(私がそれを読んで)保証されていないし、それは数えることができるのだろうかと思う。
下記の完全な例を掲載しました。
おかげで、
デイブ
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace AsynchAwaitExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
public MainWindow()
{
InitializeComponent();
}
static int beginCounter = 0;
static int endCounter = 0;
/// <summary>
/// Suggest hitting button 3 times in rapid succession
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button_Click(object sender, RoutedEventArgs e)
{
beginCounter++;
endCounter++;
// Notice that if you click fast, you'll get all the beginCounters first, then the endCounters
Console.WriteLine("beginCounter: " + beginCounter + " threadId: " + Thread.CurrentThread.ManagedThreadId);
await Function1(beginCounter);
Console.WriteLine("endCounter: " + endCounter + " threadId: " + Thread.CurrentThread.ManagedThreadId);
}
private async Task Function1(int beginCounter)
{
try
{
Console.WriteLine("about to grab lock" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
await _semaphoreSlim.WaitAsync(); // get rid of _semaphoreSlim calls and you'll get into beginning of Function2 3 times before exiting
Console.WriteLine("grabbed lock" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
await Task.Run(() => Function2(beginCounter));
}
finally
{
Console.WriteLine("about to release lock" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
_semaphoreSlim.Release();
Console.WriteLine("released lock" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
}
}
private void Function2(int beginCounter)
{
Console.WriteLine("Function2 start" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
Thread.Sleep(1000);
Console.WriteLine("Function2 end" + " threadId: " + Thread.CurrentThread.ManagedThreadId + " beginCounter: " + beginCounter);
return;
}
}
}
サンプル出力は、あなたはボタンを3回クリックした場合。 Function2は、指定されたカウンタが再び開始する前に常に終了することに注意してください。あなたはSemaphoreSlimを取り除く場合
beginCounter: 1 threadId: 9
about to grab lock threadId: 9 beginCounter: 1
grabbed lock threadId: 9 beginCounter: 1
Function2 start threadId: 13 beginCounter: 1
beginCounter: 2 threadId: 9
about to grab lock threadId: 9 beginCounter: 2
beginCounter: 3 threadId: 9
about to grab lock threadId: 9 beginCounter: 3
Function2 end threadId: 13 beginCounter: 1
about to release lock threadId: 9 beginCounter: 1
released lock threadId: 9 beginCounter: 1
grabbed lock threadId: 9 beginCounter: 2
Function2 start threadId: 13 beginCounter: 2
endCounter: 3 threadId: 9
Function2 end threadId: 13 beginCounter: 2
about to release lock threadId: 9 beginCounter: 2
released lock threadId: 9 beginCounter: 2
endCounter: 3 threadId: 9
grabbed lock threadId: 9 beginCounter: 3
Function2 start threadId: 13 beginCounter: 3
Function2 end threadId: 13 beginCounter: 3
about to release lock threadId: 9 beginCounter: 3
released lock threadId: 9 beginCounter: 3
endCounter: 3 threadId: 9
は、あなたが買ってあげる呼び出します。
beginCounter: 1 threadId: 10
about to grab lock threadId: 10 beginCounter: 1
grabbed lock threadId: 10 beginCounter: 1
Function2 start threadId: 13 beginCounter: 1
beginCounter: 2 threadId: 10
about to grab lock threadId: 10 beginCounter: 2
grabbed lock threadId: 10 beginCounter: 2
Function2 start threadId: 14 beginCounter: 2
beginCounter: 3 threadId: 10
about to grab lock threadId: 10 beginCounter: 3
grabbed lock threadId: 10 beginCounter: 3
Function2 start threadId: 15 beginCounter: 3
Function2 end threadId: 13 beginCounter: 1
about to release lock threadId: 10 beginCounter: 1
released lock threadId: 10 beginCounter: 1
endCounter: 3 threadId: 10
Function2 end threadId: 14 beginCounter: 2
about to release lock threadId: 10 beginCounter: 2
released lock threadId: 10 beginCounter: 2
endCounter: 3 threadId: 10
回答と参考に感謝します! – Dave