gpt4 book ai didi

c# - 克服共享对象线程问题的最佳解决方案

转载 作者:行者123 更新时间:2023-11-30 13:01:04 25 4
gpt4 key购买 nike

在 .net 4.0 中使用任务并行库,我想知道这种情况的最佳解决方案是什么:

我的代码正在启动一项任务,该任务执行大量长时间运行的步骤(需要一个接一个地完成这些步骤)。我有一个对象 Result,它聚合了每个步骤的结果。结果对象在任务中修改(因此在与此任务相关的线程中)。我还有一个 Web 服务,我们可以在其中获取当前的结果对象以查看任务的进度。所以 Result 对象是任务和我代码的主线程之间的共享对象。确保我没有线程问题和类似问题的最佳实现方法是什么?

这里是我正在谈论的示例。请注意,_doWork 不会像代码中那样是静态的,它将是层次结构中更高级别的另一个类中的成员。

using System.Threading.Tasks;

namespace ConsoleApplication
{
public class Step1Result
{
}

public class Step2Result
{
}

public class Result
{
public Step1Result Step1Result;
public Step2Result Step2Result;
}

class DoWork
{
public Result Result;

public DoWork()
{
Result = new Result();
}

public void Process()
{
// Execute Step 1
Result.Step1Result = Step1();
Result.Step2Result = Step2();

// Other Steps ( long - running )
}

public Step1Result Step1()
{
// Long running step that can takes minutes

return new Step1Result();
}

public Step2Result Step2()
{
// Long running step that can takes minutes

return new Step2Result();
}
}
class Program
{
private static DoWork _doWork;

static void Main(string[] args)
{
_doWork = new DoWork();

var task = Task.Factory.StartNew(() => _doWork.Process());
task.Wait();
}

// This method will be called from a web service at anytime.
static Result CalledFromWebService()
{
return _doWork.Result;
}
}
}

这里的问题是从任务和主线程访问 _doWork.Result。真的 ?可以做些什么来克服这个问题?

最佳答案

我会将 DoWork.Result 属性更改为 GetCurrentResult() 方法并每次返回当前操作结果的新副本(您可以使用 MemberwiseClone 复制对象)。我认为没有必要共享同一个对象。

另外,我会使用 ReadWriteLockSlim。所以 DoWork 类看起来像这样

class DoWork
{
private readonly Result _result;
private readonly ReadWriteLockSlim _lock = new ReadWriteLockSlim();

public DoWork()
{
_result = new Result();
}

public void Process()
{
// Execute Step 1
Step1Result st1result = Step1();
try
{
_lock.EnterWriteLock();
_result.Step1Result = st1result;
}
finally
{
_lock.ExitWriteLock();
}

Step2Result st2result = Step2();
try
{
_lock.EnterWriteLock();
_result.Step2Result = st2result;
}
finally
{
_lock.ExitWriteLock();
}

// Other Steps ( long - running )
}

public Step1Result Step1()
{
// Long running step that can takes minutes

return new Step1Result();
}

public Step2Result Step2()
{
// Long running step that can takes minutes

return new Step2Result();
}

public Result GetCurrentResult()
{
try
{
_lock.EnterReadLock();
return (Result)_result.MemberwiseCopy();
}
finally
{
_lock.ExitReadLock();
}
}

}

关于c# - 克服共享对象线程问题的最佳解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20639592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com