2012-01-13 14 views
2

以下のコードでは、「名前のリスナーは現在のコンテキストに存在しません」ローカルで宣言された変数がfinallyブロックで認識されないのはなぜですか?

本当に?どうして?

static void ReceiveSocketMsgs() 
{ 
    try 
    { 
     TcpListener listener; 
     listener = new TcpListener(IPAddress.Any, MainForm.GOHRFTrackerMainForm.socketPortNum); 
     listener.Start(); 
     using (TcpClient c = listener.AcceptTcpClient()) 
     { 
      using (NetworkStream n = c.GetStream()) 
      { 
       string msg = new BinaryReader(n).ReadString(); 
       BinaryWriter w = new BinaryWriter(n); 
       w.Write(msg + " received"); 
       w.Flush(); // Must call Flush because we're not disposing the writer. 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     //some exception (if you close the app, it will be "threadabort") 
    } 
    finally 
    { 
     listener.Stop(); 
    } 
} 

答えて

8

これは、C#スコープの動作方法です。それはlockステートメントとtry/catchステートメントで途中で取り上げられます。ただ、外の宣言を移動:

static void ReceiveSocketMsgs() 
{ 
    TcpListener listener = null; 
    try 
    { 
     listener = new TcpListener(IPAddress.Any, MainForm.GOHRFTrackerMainForm.socketPortNum); 
     ... 
    } 
    catch (Exception ex) 
    { 
     //some exception (if you close the app, it will be "threadabort") 
    } 
    finally 
    { 
     if (listener != null) 
      listener.Stop(); 
    } 
} 

はヌルとStopを呼び出す前に、それをチェックするための変数を初期化し、tryブロック内でリスナーの初期化を維持するために。

初期化を修正しました。よく目撃されたBoltClock。

+0

それとも最終的にはnullをチェック間のエリアのです。 TcpListener()から例外がスローされたらどうなりますか? –

+0

私は実際に私の最初の観測の確信していないが、多分私はちょうど疲れて休憩が必要:)どちらの方法でも、防衛プログラミングは常に良いです。 – BoltClock

+0

@BoltClock固定、ありがとうございます。あなたの観察は正しい。コードはコンパイルされませんでした:) –

6

変数をtryブロックのスコープに定義したためです。 finallyブロック内のtryブロックの外にいるので、変数にアクセスできなくなります。

単純な修正点は、リスナーをtryブロックの範囲外に宣言して、必要な場所にアクセスできるようにすることです。

2

C#はCベースの言語なので、グローバルスコープ対

{ 
    int x = 5; 

    // x is 5 here 
} 

// x is undefined out here. 

ローカルスコープ

を{}すべてで定義されている{}内のローカルです。

3

listenerが宣言されている範囲外で停止しているためです。この場合、try(catchまたはfinally)ブロックでのみ使用可能です。

2

あなたがしようスコープを考えているが、全体のtry、キャッチ(s)は、最終的にですが、スコープは{ }

関連する問題