Unë kam një aplikacion winform që funksionon në sfond me një BackgroundWorker
që ka një lak të pafund që ekzekuton diçka çdo orë. Klasa ime UI Form
është diçka si kjo:
public partial class frmAutoScript : Form
{
private volatile bool _isDownloading = false;
private bool IsDownloading { get { return this._isDownloading; } set { this._isDownloading = value; } }
public frmAutoScript()
{
InitializeComponent();
this.RunAutoSynchronization();
}
private void RunAutoSynchronization()
{
bool isDownloading = this.IsDownloading;
BackgroundWorker bgwDownloader = new BackgroundWorker();
bgwDownloader.WorkerReportsProgress = true;
bgwDownloader.ProgressChanged += (sndr, evnt) =>
{
if (evnt.ProgressPercentage == 2)
isDownloading = this.IsDownloading;
else
{
this.IsDownloading = evnt.ProgressPercentage == 1;
isDownloading = this.IsDownloading;
}
};
bgwDownloader.DoWork += (sndr, evnt) =>
{
while (true)
{
if (DateTime.Now.Hour == 16 &&
DateTime.Now.Minute == 0)
{
try
{
bgwDownloader.ReportProgress(2);
if (!isDownloading)
{
bgwDownloader.ReportProgress(1);
new Downloader().Download();
}
bgwDownloader.ReportProgress(0);
}
catch { }
}
System.Threading.Thread.Sleep(60000);
}
};
bgwDownloader.RunWorkerAsync();
}
}
Dhe në atë frmAutoScript
, kam gjithashtu një buton të quajtur btnDownload
që kur të klikohet, do të shkarkojë dhe ndryshojë vlerën e varialbesë volatile
_isDownloading
. Ngjarja e butonit është diçka si kjo:
private void btnDownload_Click(object sender, EventArgs e)
{
if (IsDownloading)
MessageBox.Show("A download is currently ongoing. Please wait for the download to finish.",
"Force Download", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
else
{
this.IsDownloading = true;
BackgroundWorker bgwDownloader = new BackgroundWorker();
bgwDownloader.DoWork += (sndr, evnt) =>
{
try
{
new Downloader().Download();
}
catch(Exception ex)
{
MessageBox.Show("An error occur during download. Please contact your system administrator.\n Exception: " +
ex.GetType().ToString() + "\nError Message:\n" + ex.Message + " Stack Trace:\n" + ex.StackTrace, "Download Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
};
bgwDownloader.RunWorkerCompleted += (sndr, evnt) =>
{
this.IsDownloading = false;
};
bgwDownloader.RunWorkerAsync();
}
}
Por kur klikoj butonin btnDownload
dhe _isDownloading
vendoset në true
, dhe kur koha e sistemit goditi 4:00 PM
, new Downloader().Download();
ekzekutohet përsëri edhe pse _isDownloading
vendoset në true. Pse ishte kështu?
Kodi im është në C#, frame 4, projekti është në winforms, i ndërtuar në Visual Studio 2010 Pro.
volatile
nuk është semantika që përdor zakonisht për të garantuar sjelljen 28.05.2012synchronized
që vendos automatikisht një bllokim rreth të gjithë aksesit në terren. Megjithatë, nuk do t'ju shpëtojë nga bllokimet. 28.05.2012