2011-08-02 4 views
1

私は(その機能のマイナーなサブセットとして)カウントダウンタイマーを提供するアプリを開発中です。しかし、複数のカウントダウンが同時に行われる場合があります。それぞれのカウントダウンにはピボットビューのピボットアイテムがあります。これらのカウントダウンは動的に作成されるので、各カウントダウンのリストのテキストブロック(残りの時間の出力として機能する)を追加しています。これらのテキストブロックを1つずつ循環するメソッドを呼び出すタイマーを設定しましたそれに応じて更新してください。しかし、私は "System.UnauthorizedAccessException"の例外を受け取っていますが、私は完全にその理由はわかりません。私はそれが "無効なクロススレッドアクセス"のエラーだと言われています。ここでWP7でタイマーを使用してテキストブロックを更新する際の問題

は、問題のあるラインであるラインです:ここでは

c.Label.Dispatcher.BeginInvoke(delegate() { c.Label.Text = timeRemaining; }); 

はフル方法である:ここでは

private static void TimeRemainingCallback(object state) 
    { 
     if (countDowns.Count == 0) 
     { 
      return; 
     } 

     foreach (CountDown c in countDowns) 
     { 
      DateTime rightNow = DateTime.Today; 

      if (c.ExpirationDate >= rightNow) 
      { 
       DateTime offsetExpiration = c.ExpirationDate.Add(c.LocalNow); 
       TimeSpan timeDifference = offsetExpiration.Subtract(rightNow); 


       String timeRemaining = ""; 
       String timeDays = ""; 
       String timeHours = ""; 
       String timeMinutes = ""; 
       String timeSeconds = ""; 

       if (timeDifference.Days == 1) 
       { 
        timeDays = "1 Day"; 
       } 
       else 
       { 
        timeDays = timeDifference.Days + " Days"; 
       } 

       if (timeDifference.Hours == 1) 
       { 
        timeHours = "1 Hour"; 
       } 
       else 
       { 
        timeHours = timeDifference.Hours + " Hours"; 
       } 

       if (timeDifference.Minutes == 1) 
       { 
        timeMinutes = "1 Minute"; 
       } 
       else 
       { 
        timeMinutes = timeDifference.Minutes + " Minutes"; 
       } 

       if (timeDifference.Seconds == 1) 
       { 
        timeSeconds = "1 Second"; 
       } 
       else 
       { 
        timeSeconds = timeDifference.Seconds + " Seconds"; 
       } 

       if (timeDifference.Days == 0 && timeDifference.Hours >= 1) 
       { 
        timeRemaining = timeHours + " " + timeMinutes; 
       } 
       else if (timeDifference.Days == 0 && timeDifference.Hours == 0 && timeDifference.Minutes >= 1) 
       { 
        timeRemaining = timeMinutes + " " + timeSeconds; 
       } 
       else if (timeDifference.Days == 0 && timeDifference.Hours == 0 && timeDifference.Minutes == 0) 
       { 
        timeRemaining = timeSeconds; 
       } 
       else 
       { 
        timeRemaining = timeDays + " " + timeHours + " " + timeMinutes; 
       } 

       c.Label.Dispatcher.BeginInvoke(delegate() { c.Label.Text = timeRemaining; }); 
      } 
     } 
    } 

は、私は、タイマー、コールバックが言及されているだけの時間を作成する方法です。

Timer updateRemainingTime = new Timer(TimeRemainingCallback, null, 0, 1000); 

リストには、実際にはdatetimeとtextblockが含まれていますラベル)従ってc.Labelの取引。

timeRemainingは、タイムカードバックで形成される残り時間の文字列です。

ここで起こっていることのアイデアはありますか?どのようにこれを行うには良いアイデアですか?

+0

'timeRemaining'をどのように変更しているのか、どこで宣言されているのかを示すコードを投稿してもよろしいですか? –

+0

@Dennis私は完全なメソッド呼び出しを追加しました... – Hosemeyer

+0

また、 'TimeRemainingCallback'はどこに呼び出され/有線(ポストコード)ですか? –

答えて

1

ループ全体の反復に対してDispatcherを呼び出し、現在のDispatcher呼び出しを削除します。

Dispatcher.BeginInvoke(() => 
{ 
    foreach (CountDown c in countDowns) 
    { 
     // Actions here. 
     c.Label.Text = timeRemaining; 
    } 
}); 

私はあなたがで作業しているリストのUIコントロールにバインドcountDownsを持っていると仮定しています。

+0

オブジェクトなしでDispatcherを使用するにはどうすればよいですか? – Hosemeyer

+0

とにかく「Timer」をどこで使っていますか?それが 'Page'の中にあれば、それに関連する' Dispatcher'をソースオブジェクトを参照せずに使うことができます。 –

+0

これはページ内ですが、非同期サービスコールのコールバックメソッド内にあります(その時点で、データがタイマーによって操作されるようになっていることがわかります)。 – Hosemeyer

関連する問題