C# 如何返回线程安全字节[]?
很抱歉发布这样一个noob问题,但我找不到答案。我还不太擅长单元测试,所以我不确定这一点。这是返回线程安全的字节[]的最佳方法吗?在这里初始化数组并在另一个线程中修改它也可以吗C# 如何返回线程安全字节[]?,c#,.net,thread-safety,C#,.net,Thread Safety,很抱歉发布这样一个noob问题,但我找不到答案。我还不太擅长单元测试,所以我不确定这一点。这是返回线程安全的字节[]的最佳方法吗?在这里初始化数组并在另一个线程中修改它也可以吗 public async Task<byte[]> GetData() { var _buffer = new byte[1024]; try { await Task.Run(() => ModifyArray(_buffer)); } catch { return null;
public async Task<byte[]> GetData()
{
var _buffer = new byte[1024];
try { await Task.Run(() => ModifyArray(_buffer)); }
catch { return null;}
return _buffer.ToArray();
}
公共异步任务GetData()
{
var_buffer=新字节[1024];
尝试{wait Task.Run(()=>ModifyArray(_buffer));}
catch{return null;}
返回_buffer.ToArray();
}
我知道ModifyArray(byte[])应该返回值,但它实际上是一个套接字接收方法。
我也在看:
public async Task<byte[]> GetData()
{
return Task.Run(() =>
{
var _buffer = new byte[1024];
try { ModifyArray(_buffer); }
catch { return null;}
return _buffer.ToArray();
});
}
公共异步任务GetData()
{
返回任务。运行(()=>
{
var_buffer=新字节[1024];
请尝试{ModifyArray(_buffer);}
catch{return null;}
返回_buffer.ToArray();
});
}
还是我应该像这样把ToArray()移到外面
public async Task<byte[]> GetData()
{
return (Task.Run(() => {...});).ToArray();
}
公共异步任务GetData()
{
return(Task.Run(()=>{…});).ToArray();
}
如果您希望返回阵列的快照,但又不希望调用者修改您的内部状态,则需要创建阵列的副本 但那不是你的情况。在方法的每次调用中创建一个新数组,而不管调用方是否修改它(假设
ModifyArray()
不存储该数组)
这意味着以下代码应该可以:
public async Task<byte[]> GetData()
{
var _buffer = new byte[1024];
await Task.Run(() => ModifyArray(_buffer));
return _buffer;
}
公共异步任务GetData()
{
var_buffer=新字节[1024];
等待任务。运行(()=>ModifyArray(_buffer));
返回缓冲区;
}
另一种选择是使用.Net与“只读数组”最接近的内容:IReadOnlyList
(在.Net 4.5中新增):
公共异步任务GetData()
{
var_buffer=新字节[1024];
等待任务。运行(()=>ModifyArray(_buffer));
返回缓冲区;
}
另外,像这样使用
wait Task.Run()
。如果您想充分使用异步,请使用真正的异步方法。如果要从UI线程中卸载一些计算,请在UI代码中执行,而不是在库中执行。线程不安全代码的标记是一个由一个线程读取,由另一个线程写入的变量。在发布的代码片段中没有明显的迹象表明,_buffer是一个局部变量,每个线程都有自己的局部变量。我们看不到ModifyArray()的功能,它可能是线程不安全的。很可能是因为它使用了一个完全未初始化的数组。但正如所发布的,没有明显的问题源。@HansPassant ModifyArray()实际上是Socket类中的Receive()。我以为任何线程都可以读取变量,但只有一个线程可以更改它?我写的第二个和第三个代码块之间有什么区别吗?针对什么故障模式的线程安全?你想避免的问题是什么?我的经验是,没有两个人对“线程安全”有相同的定义,因此如果你想要一个可靠的答案,请更具体一些。这与你的问题无关,但是,请不要这样做:catch{return null;}
。如果发生了不好的事情,您希望尽可能多地了解,因此隐藏您可能掌握的有关错误的任何信息不是一个好主意。
public async Task<IReadOnlyList<byte>> GetData()
{
var _buffer = new byte[1024];
await Task.Run(() => ModifyArray(_buffer));
return _buffer;
}