C# 后台线程安全
C# Backgroundworker threadsafety
根据内存访问,我还有一个关于线程安全的问题。
传递给 BackgroundWorker RunWorkerAsync(object) 并返回 Result 的对象的同步如何?
假设我们有 class(简化)
我们假设线程不会同时访问相同的对象。
public class WorkerArgs
{
// Do we have to sync this with lock, since bgWorker will access them?
public string FileName {get;}
public object Any {get;}
public WorkerArgs (string fileName, object any)
{
FileName = fileName;
Any = any;
}
}
...
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
WorkerArgs args = (WorkerArgs)e.Arguments
string fileName = args.FileName;
MemoryStream ms = new MemoryStream();
while ( ... )
{
.. args.Any ....
}
// Do we have to box ms and put lock arround?
e.Result = ms;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
... = (MemoryStream)e.Result ;
}
所以当两个或多个线程同时访问被禁止时,我仍然不清楚何时使用 Lock 或 Fencing。但是线程之后可以访问同一个对象。
非常感谢!
只有当一个东西被多个东西并行使用并且它的内容可以改变时才需要锁。
在您的示例中,WorkArgs
是不可变的(只能通过创建新实例来更改)。在那种情况下一切都很好。后台工作人员收到 args 对象,没有人能够更改其属性(它们是只读的)。因此不需要锁。
您的结果也是如此,因为虽然可以在 DoWork()
方法中设置该值,但 Completed()
回调获得只读 属性.
取决于您调用 DoWork()
回调的频率,也许 object Any
是更具体的内容,其中包含将从 DoWork()
更改并从外部更改的内容方法是 运行,可能需要锁。
根据内存访问,我还有一个关于线程安全的问题。
传递给 BackgroundWorker RunWorkerAsync(object) 并返回 Result 的对象的同步如何?
假设我们有 class(简化)
我们假设线程不会同时访问相同的对象。
public class WorkerArgs
{
// Do we have to sync this with lock, since bgWorker will access them?
public string FileName {get;}
public object Any {get;}
public WorkerArgs (string fileName, object any)
{
FileName = fileName;
Any = any;
}
}
...
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
WorkerArgs args = (WorkerArgs)e.Arguments
string fileName = args.FileName;
MemoryStream ms = new MemoryStream();
while ( ... )
{
.. args.Any ....
}
// Do we have to box ms and put lock arround?
e.Result = ms;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
... = (MemoryStream)e.Result ;
}
所以当两个或多个线程同时访问被禁止时,我仍然不清楚何时使用 Lock 或 Fencing。但是线程之后可以访问同一个对象。
非常感谢!
只有当一个东西被多个东西并行使用并且它的内容可以改变时才需要锁。
在您的示例中,WorkArgs
是不可变的(只能通过创建新实例来更改)。在那种情况下一切都很好。后台工作人员收到 args 对象,没有人能够更改其属性(它们是只读的)。因此不需要锁。
您的结果也是如此,因为虽然可以在 DoWork()
方法中设置该值,但 Completed()
回调获得只读 属性.
取决于您调用 DoWork()
回调的频率,也许 object Any
是更具体的内容,其中包含将从 DoWork()
更改并从外部更改的内容方法是 运行,可能需要锁。