如果使用,则从线程内部调用IEnumerable集合时会将其设置为0或null

本文关键字:设置 null 集合 IEnumerable 调用 内部 线程 如果 | 更新日期: 2023-09-27 18:24:42

我有一个在线程中运行进程的类,每当我试图在该类的List属性上使用IEnumerable方法时,它会将列表清零或使其为null。我的其他类属性保留其值。我尝试过其他类型的IEnumerable派生类,包括ConcurrentQueue和ConcurrentStack,所有派生类似乎都有相同的问题。我已经试着研究了好几天,但都无济于事。如有任何帮助,我们将不胜感激。

namespace ThreadProblem
{
public class TestMyClass
{
    public void StartTest()
    {
        MyClass testX = new MyClass(new List<BuildParam>() { BuildParam.value1, BuildParam.value2, BuildParam.value3 },"These are great comments");
        testX.TestThread();
        Console.WriteLine("testX has {0} members in the Build Parameters list",testX.BuildParameters.Count());
    }

}
public class MyClass
{
    public List<BuildParam> BuildParameters { get; set; }
    public string Comments { get; set; }

    public MyClass(List<BuildParam> parameters, string comments)
    {
        BuildParameters = parameters;
        Comments = comments;
    }
    public void TestThread()
    {
        Thread testThread = new Thread(new ThreadStart(executeProcess));
        testThread.Start();
        Thread testThread2 = new Thread(new ThreadStart(executeProcess2));
        testThread2.Start();
    }
    void executeProcess()
    {
        try
        {
            Console.WriteLine("Calling process containing IEnumerable extension method - Parameter count {0}", BuildParameters.Count());
            Console.WriteLine("Calling process containing IEnumerable extension method - Comments: {0}", Comments);
            //here is what seems to cause the issue....
            string paramsList = String.Format("Calling process containing IEnumerable extension method - These parameters will be used: {0}", String.Join(", ", BuildParameters.Select(t => t.ToString())));
            foreach (var item in BuildParameters)
            {
                //do something
                Console.WriteLine("Calling process containing IEnumerable extension method - Howdy, I am {0}", item.ToString());
            }
            Console.WriteLine("Calling process containing IEnumerable extension method - Comments Again: {0}", Comments);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    void executeProcess2()
    {
        try
        {
            Console.WriteLine("Calling process not containing IEnumerable extension method - Comments: {0}", Comments);
            foreach (var item in BuildParameters)
            {
                //do something
                Console.WriteLine("Calling process not containing IEnumerable extension method - Hi, I am {0}", item.ToString());
            }
            Console.WriteLine("Calling process not containing IEnumerable extension method - Comments again: {0}", Comments);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}    
public enum BuildParam
{
    value1,
    value2,
    value3
}
}

这会产生类似的输出:

Calling process not containing IEnumerable extension method - Comments: These are great comments
testX has 3 members in the Build Parameters list
Calling process not containing IEnumerable extension method - Hi, I am value1
Calling process not containing IEnumerable extension method - Hi, I am value2
Calling process not containing IEnumerable extension method - Hi, I am value3
Calling process not containing IEnumerable extension method - Comments again: These are great comments
Calling process containing IEnumerable extension method - Parameter count 3
Calling process containing IEnumerable extension method - Comments: These are great commentscomments

如果使用,则从线程内部调用IEnumerable集合时会将其设置为0或null

我怀疑这一行抛出了一个异常:

//here is what seems to cause the issue....
string paramsList = String.Format("Calling process containing IEnumerable extension method - These parameters will be used: {0}", String.Join(", ", BuildParameters.Select(t => t.ToString())));

将其封装在try/catch中,并输出异常信息:

string paramsList;
try
{
    string parms = string.Join(", ",  BuildParameters.Select(t => t.ToString())));
    paramsList = String.Format(
        "Calling process containing IEnumerable extension method - These parameters will be used: {0}",
        parms);
    Console.WriteLine(paramsList);
}
catch (Exception ex)
{
    Console.WriteLine("Exception!");
    Console.WriteLine(ex.ToString());
}

或者你可以把你的整个线程进程都包在里面。不过要小心。您不应该盲目地在生产代码中捕获所有这样的异常。它很适合调试,但不要把它留在生产代码中。

您的executeProcess线程因异常而中止。仅仅重新思考是不够的。尝试添加这个,例如在您的主要方法中:

AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
{
    // TODO: Here, you can access the exception as a parameter of e.
    // So you can debug it, log it, output it, store it in a file, whatever.
}