EDIT2--> 一番下を見てください。 <--EDIT2
私は(少なくとも私にとっては)奇妙な行動に遭遇しました。
簡単な WinForms クラスと簡単なクラス (以下のコード) を作成してテストしました。
lock(m_lock)
前のlock(m_lock)
呼び出しが終了していない場合、最初の呼び出しは待機して1回入力し、2番目の呼び出しはロックの範囲を離れると常に考えていました。いいえ。
アクションの流れは次のとおりです。
Class1
オブジェクトを作成します。Start()
メソッドを呼び出します。メソッドでロックされて
DoSomething()
いる間にメソッドを呼び出します。m_lock
run
出力は次のとおりです。
始める()
ロックを取得しようとしています
獲得したロック
ロック解除
ロックを取得しようとしています
獲得したロック
DoSomething() ロックを取得しようとしています
...ハング...
私は何が欠けているか、間違っていますか? 私はC#(C ++から来た)の初心者なので、C#にはいくつかの落とし穴があるかもしれません。
そして、まだハングアップしています...(この投稿を書き終えるまでに)
編集-->
現実の世界では、ロックを使用してserialPortの読み取り/書き込み/構成を保護します(非同期ではなく同期読み取り/書き込みを使用)。WaitOne
そして、いくつかの内部呼び出しがあることを dbg で確認します。関連性があるかどうかはわかりません。
<--編集
例を次に示します。
using System;
namespace LockTester
{
public class Class1
{
object m_lock = null;
bool m_isRunning;
System.Threading.Thread m_thread = null;
public Class1()
{
Console.WriteLine("Class1 ctor");
m_lock = new object();
m_isRunning = false;
}
public void DoSomething(){
Console.WriteLine("DoSomething() Trying to acquire lock");
lock(m_lock){
Console.WriteLine("DoSomething() Acquired lock");
}
Console.WriteLine("DoSomething() Released lock");
}
public void Start(){
Console.WriteLine("start()");
m_isRunning = true;
if (m_thread == null){
m_thread = new System.Threading.Thread(Run);
}
m_thread.Start();
}
public void Stop(){
Console.WriteLine("stop()");
m_isRunning = false;
}
private void Run(){
while (m_isRunning){
Console.WriteLine("Trying to acquire lock");
lock(m_lock){
Console.WriteLine("Acquired lock");
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Released lock");
System.Threading.Thread.Sleep(1000);
}
}
}
}
EDIT2:
わかりました、答えが見つかりました。それはもう1つの共通点にありました。
コンソール出力を TextBox にリダイレクトするソリューションをどこかで (SO おそらく) 見つけました (純粋にテスト上の理由から、コンソールに出力されるテスト対象オブジェクトの内部メッセージをキャプチャできる、GUI を使用した小さなテスト アプリケーション)。
コードは次のとおりです。
私のフォームのコンストラクターで次のように使用されます:
_writer = new TextBoxStreamWriter(textBox1, this);
Console.SetOut(_writer);
public class TextBoxStreamWriter : TextWriter
{
TextBox _output = null;
Form _form = null;
object _lock = new object();
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (_output.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
_form.Invoke(d, new object[] { text });
}
else
{
_output.AppendText(text);
}
}
public TextBoxStreamWriter(TextBox output, Form form)
{
_output = output;
_form = form;
}
public override void Write(char value)
{
lock (_lock)
{
base.Write(value);
SetText(value.ToString());
}
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
なぜこれがこの問題を引き起こしたのか、誰でも説明できますか?