2

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

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

    return _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();
    });
}

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

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

任何见解将不胜感激。

4

1 回答 1

2

如果要返回数组的快照,则需要创建数组的副本,但不希望调用者修改内部状态。

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

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

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

另一种选择是使用 .Net 最接近“只读数组”的东西:(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()这样使用通常不是一个好主意。如果您想充分利用异步,请使用真正的异步方法。如果您想从 UI 线程中卸载一些计算,请在 UI 代码中执行此操作,而不是在您的库中。

于 2013-07-06T19:17:53.017 回答