1

这是关于AutoResetEventC# 中的。我试图阅读其他答案,但我无法理解并适用于我的场景。我没有写任何线程应用程序。只是一个小应用程序来读取/验证文件和更新。所以我有这个要求写一些代码来读取一个固定长度的文件,验证它,然后如果它是有效的,将它上传到数据库。

我得到了一切工作,直到我被困在AutoResetEvent. 这就是正在发生的事情。解析/读取数据后,我使用 C# 中的平面文件检查器实用程序对其进行验证。所以我将这些函数调用到我的应用程序中。这是片段。

private AutoResetEvent do_checks = new AutoResetEvent(false);
public bool ValidationComplete = false;

这部分进入初始化代码:

this._files.Validated += new EventHandler<SchemaValidatedEventArgs>(FileSetValidated);

public bool ValidateFile()
{
    try
    {
        RunValidation(); 
        return true;
    }
    catch (Exception e)
    {
        log.Error("Data Validation failed because :" + e.Message);
        return false;
    }
}

private void RunValidation()
{
    // Use Flat File Checker user interface to create Schema file.
    do_checks = _files.RunChecks();
    log.Debug("Validation Started");
}

这是在验证过程中被异步调用的方法:

public void FileSetValidated(Object sender, SchemaValidatedEventArgs e)
{   
    try
    {                 
        ValidationComplete = e.Result;

        if (IsDataValid)
        {
            log.Debug("Data is validated and found to be valid.");
        }
        else
        {
            log.Debug("Data is validated and found to be Invalid");
        }
    }
    finally
    {
        do_checks.Set();
    }
}

发生的情况是,即使在我将任何值设置到ValidationComplete代码中之前,也会检查验证是否完成,并且因为它默认设置为 false,所以它返回 false。之后执行代码中的代码FileSetValidated,因此数据库更新永远不会发生。

原因是我无法更改代码,因为平面文件检查器只接受一个AutoResetEvent作为 RunChecks 方法中的返回变量。

** * ***这是我现在所做的* ** * ** * private AutoResetEvent do_checks;

public bool ValidateFile()
    {

        try
        {

            string extFilePath = surveyFile.ExtFilePath;
            File.Copy(extFilePath, localTempFolder + "ExtractFile.Dat");
            RunValidation();

            if (!do_checks.WaitOne(TimeSpan.FromSeconds(30))) { 

            //    throw new  ApplicationException("Validation took more than expected!"); 
            }    

            return true;
        }
        catch (Exception e)
        {
            log.Error("Data Validation failed because :" + e.Message);
            return false;

        }



    }


    private void RunValidation()
    {
        // Use Flat File Checker user interface to create Schema file.
        do_checks = _files.RunChecks();
        do_checks.WaitOne();
        log.Debug("Validation Started");


    }

此外,我将传递有关验证的数据的部分移到事件处理程序的开头,以便至少执行该部分。这有帮助,但我不确定它是否正确。

4

2 回答 2

1

我从来没有使用过那个库,所以我只是下载了它并查看了代码。

首先,正如已经提到的“500 - Internal Server Error”,似乎缺少部分代码,至少在 FileSetValidated 方法中“尝试”。我没有看到您正在通过WaitOne等待事件的任何地方。

您不需要自己创建do_checks,因为_files.RunChecks()会为这个特定文件的处理创建 AutoResetEven。因此,如果您对该事件使用相同的字段 - 如果您需要同时处理几个文件,您将遇到问题。因此,为每个文件保留单独的事件,在任何情况下,如果您不想在中间停止处理(如果您在处理期间调用do_checks.Set(),它会取消处理而不完成它)。

正如我在 lib 代码中看到的,你不应该在FileSetValidated方法中调用do_checks.Set(),因为它会被设置,一旦处理完成,你可以写:

var do_checks = _files.RunChecks();
do_checks.WaitOne(); 

如果有帮助,请随时分享。

更新: 我现在无法检查该 lib 以了解为什么在开始处理后设置了do_checks,但我可以建议您将初始代码与下一个RunValidation方法一起使用:

private void RunValidation()
{
    do_checks.Reset(); //reset state
    _files.RunChecks(); //don't store event from the lib
    log.Debug("Validation Started");
    do_checks.WaitOne(); //Wait for FileSetValidated to set this event
}
于 2011-11-09T01:40:38.090 回答
0

在退出 ValidateFile 函数之前,您需要等待验证完成(等待 AutoResetEvent)并返回验证结果。

尝试这样的事情:

public bool ValidateFile()
{
    //try
    {
        RunValidation();

        //Allocate enough time for the validation to occur but make sure 
        // the application doesn't block if the _files.Validated event doesn't get fired
        if(!do_checks.WaitOne(TimeSpan.FromSeconds(10)))
        {
            throw ApplicationException("Validation took more than expected!");
        }            

        return ValidationComplete;
    }
    //I would not catch the exception since having an error doesn't mean that the file 
    //is invalid. Catch it upper in the call stack and inform the user that the validation 
    //could not be performed because of the error
    //catch (Exception e)
    //{
    //     log.Error("Data Validation failed because :" + e.Message);
    //     return false;
    //}
 }
于 2011-11-09T01:17:05.713 回答