在长时间运行的线程上设置类属性

时间:2013-07-15 07:01:49

标签: c# .net multithreading task threadpool

我正在填充一些类属性,

其中一个涉及将实体结构序列化为byte []这需要一些时间,所以我想在一个线程中完成它。

值永远不会被设置,因为我假设类和线程现在超出了范围。

代码如下,任何想法都将受到赞赏

   public class classA
{
    public void DoSomething()
    {
        var classC = new ClassB().DoSomethingElse();

        //SAVE CLASS c to database
        var serialized = classC.GetSerializedDataTable(); // is always null unless i take out the task from class c
    }
}

public class ClassB
{
    public ClassC DoSomethingElse()
    {
        var classC = new ClassC();

        classC.DataTableValue = new DataTable();
        classC.SerializeToByteArray();
        return classC;
    }
}

public class ClassC
{
    public DataTable DataTableValue { get; set; }
    private byte[] serializedData;


    public void SerializedDataTable()
    {
        new Task(() => this.serializedData = this.DataTableValue.SerializeToByteArray()).Start();
    }


    public byte[] GetSerializedDataTable()
    {
        return this.serializedData;
    }

}

1 个答案:

答案 0 :(得分:0)

Task不仅仅用于在另一个线程上运行代码,它代表一个逻辑工作单元,一旦完成就可以返回一些东西。

您的ClassC.GetSerializedDataTable()似乎是使用Task<byte[]>返回类型的理想场所:

public class ClassC
{
    public DataTable DataTableValue { get; set; }
    private Task<byte[]> serializeDataTask;

    public void SerializeDataTable()
    {
        serializeDataTask = Task.Factory.StartNew( () => this.DataTableValue.SerializeToByteArray() );
    }

    public Task<byte[]> GetSerializedDataTable()
    {
        // You can either throw or start it lazily if SerializeDataTable hasnt been called yet.
        if ( serializeDataTask == null ) 
            throw new InvalidOperationException();
        return serializeDataTask;
    }
}

现在您的客户端代码可以以智能方式使用Task返回类型。如果结果已经可用,它可以通过Task.Result立即使用它。否则它可以等待它完成,或者在完成之前执行一些其他工作。关键是调用代码现在具有采用最合适的操作过程的上下文。

回到你的例子:

public void DoSomething()
{
    var classC = new ClassB().DoSomethingElse();

    //SAVE CLASS c to database
    var serializeTask = classC.GetSerializedDataTable();
    // will obtain result if available, will block current thread and wait for serialized data if task still running.
    var serializedData = serializeTask.Result; 
}