Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何返回线程安全字节[]?_C#_.net_Thread Safety - Fatal编程技术网

C# 如何返回线程安全字节[]?

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;

很抱歉发布这样一个noob问题,但我找不到答案。我还不太擅长单元测试,所以我不确定这一点。这是返回线程安全的字节[]的最佳方法吗?在这里初始化数组并在另一个线程中修改它也可以吗

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;
}