如果条件为真且在特定时间段内,如何仅执行一次方法

时间:2017-07-27 17:04:51

标签: c# .net multithreading

目前我正在开发一个C#应用程序,我必须压缩一个给定的文件夹,然后将该压缩文件上传到给定的URL(服务器)。为此,我创建了两种方法来创建zip文件(CreateZipFile),然后上传(UploadZipFile)它。

这两种方法可以由不同的用户(不同的线程)同时调用。在执行CreateZipFile方法之前,我需要检查哪个线程请求压缩的文件夹是否相同,如果是,我需要以1分钟的时间间隔执行该方法一次(因为文件夹在1分钟的时间段内没有更新)不需要为同一个文件夹创建多个zip文件)。但是,如果线程请求压缩不同的文件夹,那么我需要为每个文件夹创建zip文件。

这是我实施的CreateZipFile方法

private static string CreateZipFile(string sourceDirPath)
    {
        string zipFileName = "";
        try
        {
            // Construct the zip file name
            zipFileName = new DirectoryInfo(sourceDirPath).Name + ".zip";

            if (File.Exists(zipFileName))
            {
                File.Delete(zipFileName);
            }

            ZipFile.CreateFromDirectory(sourceDirPath, zipFileName);
        }
        catch (Exception ex)
        {
            logger.Error("CreateZipDirectory", ex);
        }

        return zipFileName;
    }

这是我实施的UploadZipFile方法

private bool UploadZipFile(string sourceFilePath, string destinationUrl)
    {
        bool status = false;

        for (int retryAttempt = 1; retryAttempt <= MAX_RETRY_ATTEMPTS; retryAttempt++)
        {
            try
            {
                string fileNameWOExt = Path.GetFileNameWithoutExtension(sourceFilePath);
                var client = new HttpClient();
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + access_token);
                var content = new MultipartFormDataContent();
                content.Add(new StreamContent(File.Open(sourceFilePath, FileMode.Open)), fileNameWOExt, sourceFilePath);
                var result = client.PostAsync(destinationUrl, content);

                if ((Int32)result.Result.StatusCode == 200)
                {
                    status = true;
                    logger.Info("UploadLogDirectory", "Log directory uploaded successfully");
                }
                else
                {
                    logger.Info("UploadLogDirectory", "Upload Error: Status " + (Int32)result.Result.StatusCode);
                }

                break;
            }
            catch (Exception ex)
            {
                if(ex is AggregateException)
                {
                    if (retryAttempt <= MAX_RETRY_ATTEMPTS)
                    {
                        System.Threading.Thread.Sleep(1000);
                        continue;
                    }
                    else
                    {
                        throw;
                    }
                }
                throw;
            }
        }

        return status;
    }

这就是我称之为这些方法的方法

private void ExportLogDirectory(TaskBase taskObj)
    {
        bool status = false;
        try
        {
            string directoryPath = taskObj.GetParam("DirectoryPath").GetValue();
            string destinationUrl = taskObj.GetParam("destinationUrl").GetValue();

            // Zip the log directory
            string createdZipFile = CreateZipFile(directoryPath);


            // Upload the zipped log directory
            status = UploadZipFile(createdZipFile, destinationUrl);

            if(status)
            {
                Console.WriteLine("SUCCESS");
            }
            else
            {
                Console.WriteLine("FAIL")
            }
        }
        catch(Exception ex)
        {
            logger.Error("ExportLogDirectory", ex);
        }

我需要知道在执行CreateZipFile方法之前如何检查每个线程请求压缩的文件夹是否相同?如果我可以获得这个,那么我可以同步方法或根据它锁定它。

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您应该追踪上次压缩文件夹的时间并在此基础上做出决定。

ConcurrentDictionary<string, DateTime> zipTimes = new ConcurrentDictionary<string, DateTime>();

在CreateZipFile()中,在开始时在try块中添加以下行。

DateTime updatedTime;
if( zipTimes.TryGetValue( sourceDirPath, out updatedTime ) && ( DateTime.Now - updatedTime ).TotalMinutes < 1 )
    return;
zipTimes [ sourceDirPath ] = DateTime.Now;