Timer.SynchronizingObject Proprietà
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Ottiene o imposta l'oggetto usato per effettuare il marshalling delle chiamate del gestore eventi generate alla scadenza di un intervallo.
public:
property System::ComponentModel::ISynchronizeInvoke ^ SynchronizingObject { System::ComponentModel::ISynchronizeInvoke ^ get(); void set(System::ComponentModel::ISynchronizeInvoke ^ value); };
public System.ComponentModel.ISynchronizeInvoke SynchronizingObject { get; set; }
public System.ComponentModel.ISynchronizeInvoke? SynchronizingObject { get; set; }
[System.Timers.TimersDescription("TimerSynchronizingObject")]
public System.ComponentModel.ISynchronizeInvoke SynchronizingObject { get; set; }
[System.Timers.TimersDescription("TimerSynchronizingObject")]
[System.ComponentModel.Browsable(false)]
public System.ComponentModel.ISynchronizeInvoke SynchronizingObject { get; set; }
member this.SynchronizingObject : System.ComponentModel.ISynchronizeInvoke with get, set
[<System.Timers.TimersDescription("TimerSynchronizingObject")>]
member this.SynchronizingObject : System.ComponentModel.ISynchronizeInvoke with get, set
[<System.Timers.TimersDescription("TimerSynchronizingObject")>]
[<System.ComponentModel.Browsable(false)>]
member this.SynchronizingObject : System.ComponentModel.ISynchronizeInvoke with get, set
Public Property SynchronizingObject As ISynchronizeInvoke
Valore della proprietà
ISynchronizeInvoke che rappresenta l'oggetto usato per effettuare il marshalling delle chiamate del gestore eventi generate alla scadenza di un intervallo. Il valore predefinito è null
.
- Attributi
Esempio
L'esempio seguente è un'app Windows Forms che funge da editor di file di testo molto semplice. Quando il testo nella casella di testo non è stato salvato, l'app chiede all'utente a intervalli di un minuto se desidera salvare il contenuto della casella di testo. A tale scopo, la Interval proprietà viene impostata su un minuto (60.000 millisecondi) e la SynchronizingObject proprietà viene impostata sull'oggetto Form .
using System;
using System.IO;
using Timers = System.Timers;
using System.Windows.Forms;
public partial class Form1 : Form
{
Timers.Timer timer = null;
StreamWriter sw = null;
bool hasChanged = false;
bool dialogIsOpen = false;
int elapsedMinutes = 0;
// Cache the text box cache internally without saving it.
String txt = "";
public Form1()
{
InitializeComponent();
this.Text = "Quick Text Editor";
button1.Text = "Save";
textBox1.Multiline = true;
// Configure the SaveFile dialog
saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1.RestoreDirectory = true;
// Create a timer with a 1-minute interval
timer = new Timers.Timer(60000);
// Define the event handler
timer.Elapsed += this.PromptForSave;
// Synchronize the timer with the text box
timer.SynchronizingObject = this;
// Start the timer
timer.AutoReset = true;
}
private void PromptForSave(Object source, Timers.ElapsedEventArgs e)
{
if (hasChanged & (!dialogIsOpen)) {
elapsedMinutes++;
dialogIsOpen = true;
if (MessageBox.Show(String.Format("{0} minutes have elapsed since the text was saved. Save it now? ",
elapsedMinutes), "Save Text",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
{
button1_Click(this, EventArgs.Empty);
dialogIsOpen = false;
}
}
}
private void button1_Click(Object sender, EventArgs e)
{
if (String.IsNullOrEmpty(saveFileDialog1.FileName)) {
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
sw = new StreamWriter(saveFileDialog1.FileName, false);
}
txt = textBox1.Text;
hasChanged = false;
timer.Stop();
}
private void form1_FormClosing(Object sender, FormClosingEventArgs e)
{
if (sw != null) {
sw.Write(txt);
sw.Close();
}
}
private void textBox1_TextChanged(Object sender, EventArgs e)
{
hasChanged = true;
timer.Start();
}
}
Imports System.IO
Imports System.Timers
Public Class Form1
' Create the timer to fire at a 60-second interval.
Dim WithEvents timer As New System.Timers.Timer(60000)
Dim sw As StreamWriter
Dim hasChanged As Boolean
Dim dialogIsOpen As Boolean = False
Dim elapsedMinutes As Integer = 0
' Cache the text box internally without saving it.
Dim txt As String = ""
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.Text = "Quick Text Editor"
Button1.Text = "Save"
TextBox1.Multiline = True
' Configure the SaveFile dialog
SaveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
SaveFileDialog1.RestoreDirectory = True
' Create a timer with a 1-minute interval
timer = New Timer(2000)
' Synchronize the timer with the text box
timer.SynchronizingObject = Me
' Start the timer
timer.AutoReset = True
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
hasChanged = True
timer.Start()
End Sub
Friend Sub PromptForSave(sender As Object, e As ElapsedEventArgs) _
Handles timer.Elapsed
If hasChanged And Not dialogIsOpen Then
elapsedMinutes += 1
dialogIsOpen = True
If MsgBox(String.Format("{0} minutes have elapsed since the text was saved. Save it now? ",
elapsedMinutes), MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Question,
"Save Text") = MsgBoxResult.Yes Then
If dialogIsOpen Then
Button1_Click(Me, EventArgs.Empty)
dialogIsOpen = False
End If
End If
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If String.IsNullOrEmpty(SaveFileDialog1.FileName) Then
If SaveFileDialog1.ShowDialog() = DialogResult.OK Then
sw = New StreamWriter(SaveFileDialog1.FileName, False)
End If
End If
txt = TextBox1.Text
hasChanged = False
elapsedMinutes = 0
timer.Stop()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
If sw IsNot Nothing Then
sw.Write(txt)
sw.Close()
End If
End Sub
End Class
L'esempio richiede l'aggiunta dei controlli seguenti al form:
Controllo TextBox denominato
TextBox1
(nome predefinito).Controllo Button denominato
Button1
(nome predefinito).Controllo SaveFileDialog denominato
SaveSaveFileDialog1
(nome predefinito) .
Commenti
Quando SynchronizingObject è null
, il metodo che gestisce l'evento Elapsed viene chiamato su un thread dal pool di thread di sistema. Per altre informazioni sui pool di thread di sistema, vedere ThreadPool.
Quando l'evento Elapsed viene gestito da un componente visivo Windows Forms, ad esempio un pulsante, l'accesso al componente tramite il pool di thread di sistema potrebbe causare un'eccezione o semplicemente non funzionare. Evitare questo effetto impostando SynchronizingObject su un componente Windows Forms, che determina la chiamata del metodo che gestisce l'evento Elapsed nello stesso thread in cui è stato creato il componente.
Nota
Anche se la SynchronizingObject proprietà non null
è , Elapsed gli eventi possono verificarsi dopo che il Dispose metodo o Stop è stato chiamato o dopo che la Enabled proprietà è stata impostata su false
, perché il segnale per generare l'evento viene sempre accodato per l'esecuzione Elapsed in un thread del pool di thread. Un modo per risolvere questa race condition consiste nell'impostare un flag che indica al gestore eventi per l'evento Elapsed di ignorare gli eventi successivi.
Se viene Timer usato in Visual Studio in una finestra di progettazione di Windows Forms, SynchronizingObject viene automaticamente impostato sul controllo che contiene .Timer Ad esempio, se si inserisce un Timer oggetto in una finestra di progettazione per Form1
(che eredita da Form), la SynchronizingObject proprietà di Timer viene impostata sull'istanza di Form1
.