0

上司と労働者の同期を正しく行うのに問題があります。問題は、SyncWorkerが完了する前にSyncManagerが停止していることです...そして、SyncWorkerが終了するのを待たずにSyncManagerが実行を継続している理由がわかりません。

SyncManager

public void ExecuteTask()
{
    /*Code to set up Variables*/
    while (fileMetadata.Count > 0 && Status != WorkerStatus.ShouldStop)
    {
        if (DateTime.Now.Subtract(lastUpdate).Minutes > 1)
            _serviceLog.WriteEntry(ProgressString());

        if (Status == WorkerStatus.ShouldStop)
            break;

        SyncFile(fileMetadata[0]);

        //Possible solution
        //Wait for Sync File to Finish before stepping (although logically it should do that)

        if (DateTime.Now.Subtract(lastUpdate).Minutes > 1)
            _serviceLog.WriteEntry(ProgressString());

        //Code That I think is causing the error
        fileMetadata.RemoveAt(0);
    }
    /*Code to preform clean up actions and notify user of all transfers*/
}

public void SyncFile(FileMetadata fmd)
    {
        lock (executionLock)
        {
            attempts++;
            long waitTime = 0;
            switch (Type)
            {
                case (SyncManagerType.UploadLarge):
                    waitTime = 8192;
                    break;
                case (SyncManagerType.UploadMedium):
                    waitTime = 4096;
                    break;
                case (SyncManagerType.DownloadLarge):
                    waitTime = 8192;
                    break;
                case (SyncManagerType.DownloadMedium):
                    waitTime = 4096;
                    break;
                default:
                    waitTime = 30;
                    break;
            }

            syncWorker = new FileSyncWorker(GenerateSyncWorkerID(), _serviceLog, fmd, ref sb);
            syncThread = new Thread(new ThreadStart(syncWorker.ExecuteTask));
            syncThread.Start();
            DateTime start = DateTime.Now;
            DateTime finish;

            while (DateTime.Now.Subtract(start).TotalSeconds < waitTime && (syncWorker.Status == WorkerStatus.Working))
            {
                if (DateTime.Now.Subtract(lastUpdate).Minutes > 1)
                    _serviceLog.WriteEntry(ProgressString());

                if (Status == WorkerStatus.ShouldStop)
                    waitTime = 15;

                Thread.Sleep(1000);
            }

            finish = DateTime.Now;

            Thread.Sleep(1000);
            if (finish.Subtract(start).TotalSeconds < waitTime)
            {
                if (syncWorker.Status == WorkerStatus.CompletedSuccess)
                {
                    successes++;
                }
            }
            else
            {
                syncThread.Abort();
                sb.AppendLine("Sync Manager (" + ID + ") - FSW (" + syncWorker.ID + ") - Transfer timed out after " + waitTime + " seconds.");
            }

            //Possible Solution
            //FileMetadata toRemove = fileMetadata.Find(delegate(FileMetadata f) { return f.Equals(syncWorker.FileData); });
            //fileMetadata.Remove(toRemove);

            activeIDs.RemoveAll(delegate(int i) { return i == syncWorker.ID; });
            syncWorker = null;

            Thread.Sleep(1000);
        }
    }
4

1 に答える 1

1

親スレッドがワーカーを待機するようにする場合は、Thread.Join終了する前に必ず前に配置してください。

if (finish.Subtract(start).TotalSeconds < waitTime)
{
     if (syncWorker.Status == WorkerStatus.CompletedSuccess)
     {
          successes++;
     }
}
else
{
     syncThread.Abort();
     syncThread.Join();
     sb.AppendLine("Sync Manager (" + ID + ") - FSW (" + syncWorker.ID + ") - Transfer timed out after " + waitTime + " seconds.");
}
于 2012-07-11T19:10:35.233 に答える