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

时间:2013-07-05 22:59:47

标签: c# .net thread-safety

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

public async Task<byte[]> GetData()
{
    var _buffer = new byte[1024];
    try { await Task.Run(() => ModifyArray(_buffer)); }
    catch { return null;}

    return _buffer.ToArray();
}

我知道ModifyArray(byte [])应该返回值,但它实际上是一个Socket Receive方法。 我也在看:

public async Task<byte[]> GetData()
{
    return Task.Run(() => 
    {
        var _buffer = new byte[1024];
        try { ModifyArray(_buffer); }
        catch { return null;}

        return _buffer.ToArray();
    });
}

或者我应该像这样将ToArray()移到外面

public async Task<byte[]> GetData()
{
    return (Task.Run(() => {...});).ToArray();
}

非常感谢任何见解。

1 个答案:

答案 0 :(得分:2)

如果要返回阵列的快照,但是不希望调用者修改内部状态,则必须创建阵列的副本。

但那不是你的情况。您在方法的每次调用中创建一个新数组,并且您不关心调用者是否修改它(假设ModifyArray()不存储数组)。

这意味着以下代码应该没问题:

public async Task<byte[]> GetData()
{
    var _buffer = new byte[1024];
    await Task.Run(() => ModifyArray(_buffer));
    return _buffer;
}

另一个选择是使用最接近的东西.Net必须“readonly array”:IReadOnlyList<T>(.Net 4.5中的新内容):

public async Task<IReadOnlyList<byte>> GetData()
{
    var _buffer = new byte[1024];
    await Task.Run(() => ModifyArray(_buffer));
    return _buffer;
}

此外,使用await Task.Run()之类的是often not a good idea。如果要充分利用异步,请使用真正的异步方法。如果您想从UI线程卸载一些计算,请在UI代码中执行,而不是在库中。