ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#异步案例一则

2019-12-08 11:04:19  阅读:308  来源: 互联网

标签:异步 www ajzmzp C# atricle 案例 auto com htmlhttp


场景

  生产者和消费者队列, 生产者有多个, 消费者也有多个, 生产到消费需要异步.

下面用一个Asp.NetCore Web-API项目来模拟#

  创建两个API, 一个Get(), 一个Set(), Get返回一个字符串, Set放入一个字符串, Get返回的就是Set进去的字符串.

  实现如下:  

复制代码
[Route("api/[controller]/[action]")]
public class FooController : Control
{
    IMessageQueue _mq;
    public FooController(IMessageQueue mq)
    {
        _mq = mq;
    }

    [HttpGet]
    public string Get()
    {
        string str = _mq.ReadOne<string>();
        return str;
    }

    [HttpGet]
    public void Set(string v)
    {
        _mq.WriteOne(v);
    }
}

public interface IMessageQueue
{
    T ReadOne<T>();
    void WriteOne<T>(T value);
}

public class MessageQueue: IMessageQueue
{
    private object _value;

    public T ReadOne<T>()
    {
        return (T)_value;
    }

    public void WriteOne<T>(T value)
    {
        _value = value;

    }
}
复制代码

接着在StartUp中把IMessageQueue给注入了.

services.AddSingleton<IMessageQueue, MessageQueue>();

运行后, 先调用/api/foo/set/?v=xxx, 再调用/api/foo/get/

可以看到成功返回了xxx

第二步, value字段改为队列:#

使set进去的值不会被下一个覆盖, get取队列最前的值

为了线程安全, 这里使用了ConcurrentQueue<T>

代码如下:

复制代码
public class MessageQueue: IMessageQueue
{
    private readonly ConcurrentQueue<object> _queue = new ConcurrentQueue<object>();

    public T ReadOne<T>()
    {
        _queue.TryDequeue(out object str);
        return (T)str ;
    }

    public void WriteOne<T>(Tvalue)
    {
        _queue.Enqueue(value);
    }
}
复制代码

那么此时, 只要get不断地轮询, 就可以取到set生产出来的数据了.

调用/api/foo/set/

三, 异步阻塞#

再增加需求, 调换get和set的顺序,先get后set模拟异步, (我这里的demo是个web-api会有http请求超时之类的...假装不存在)我想要get调用等待有数据时才返回.

也就是说我想要在浏览器地址栏输入http://localhost:5000/api/foo/get/之后会不断地转圈直到我用set接口放入一个值

方案A: while(true), 根本无情简直无敌, 死等Read() != null时break; 为防单核满转加个Thread.Sleep();

方案B: Monitor, 一个Wait()一个Exit/Release();

但是以上两个方案都是基于Thread的, .Net4.0之后伴随ConcurrentQueue一起来的还有个BlockingCollection<T>相当好用

方案C: 修改后代码如下:

复制代码
public class MessageQueue : IMessageQueue
{
    private readonly BlockingCollection<object> _queue = new BlockingCollection<object>(new ConcurrentQueue<object>());

    public T ReadOne<T>()
    {
        var obj = _queue.Take();
        return (T)obj;
    }

    public void WriteOne<T>(T value)
    {
        _queue.Add(value);
    }
}
复制代码

此时, 如果先get, 会阻塞等待set; 如果已经有set过数据就会直接返回队列中的数据. get不会无功而返了. 基于这个类型, 可以实现更像样的订阅模型.

扩展RPC#

这里的set是生产者, get是消费者, 那如果我的这个生产者并不单纯产生数据返回void而是需要等待一个结果的呢? 此时订阅模型不够用了, 我需要一个异步的RPC .

比如有个Ask请求会携带参数发起请求, 并等待, 知道另外有个地方处理了这个任务产生结果, ask结束等待返回这个结果answer. 

我可以回头继续用方案A或B, 但连.net4.0都已经过去很久了, 所以应该用更好的基于Task的异步方案.

代码如下, 首先新增两个接口:

复制代码
public interface IMessageQueue
{
    void Respond<TRequest, TResponse>(Func<TRequest, TResponse> func);
    Task<TResponse> Rpc<TRequest, TResponse>(TRequest req);

    T ReadOne<T>();
    void WriteOne<T>(T data);
}
复制代码

接着定义一个特殊的任务类:

public class RpcTask<TRequest, TResponse>
{
    public TaskCompletionSource<TResponse> Tcs { get; set; }
    public TRequest Request { get; set; }
}

实现刚才新加的两个接口:

复制代码
public Task<TResponse> Rpc<TRequest, TResponse>(TRequest req)
{
    TaskCompletionSource<TResponse> tcs = new TaskCompletionSource<TResponse>();
    _queue.Add(new RpcTask<TRequest, TResponse> { Request = req, Tcs = tcs});
    return tcs.Task;
}

public void Respond<TRequest, TResponse>(Func<TRequest, TResponse> func)
{
    var obj = _queue.Take();
    if(obj is RpcTask<TRequest, TResponse> t)
    {
        var response = func(t.Request);
        t.Tcs.SetResult(response);
    }
}
复制代码

同样的, 写两个Web API接口, 一个请求等待结果 一个负责处理工作

复制代码
[HttpGet]
public async Task<string> Ask(string v)
{
    var response = await _mq.Rpc<MyRequest, MyResponse>(new MyRequest { Id = v });
    return $"[{response.DoneTime}] {response.Id}";
}

[HttpGet]
public void Answer()
{
    _mq.Respond<MyRequest, MyResponse>((req)=> new MyResponse { Id = req.Id, DoneTime = DateTime.Now });
}
复制代码

上面还随便写了两个class作为请求和返回

复制代码
public class MyRequest
{
    public string Id { get; set; }
}
public class MyResponse
{
    public string Id { get; set; }
    public DateTime DoneTime { get; set; }
}
复制代码

测试一下, 用浏览器或postman打开三个选项卡, 各发起一个Ask接口的请求, 参数v分别为1 2 3, 三个选项卡都开始转圈等待

然后再打开一个选项卡访问answer接口, 处理刚才放进队列的任务, 发起一次之前的三个选项卡之中就有一个停止等待并显示返回数据. 需求实现.

这里用到的关键类型是TaskCompletionSource<T>.

再扩展#

如果是个分布式系统, 请求和处理逻辑不是在一个程序里呢? 那么这个队列可能也是一个单独的服务. 此时就要再加个返回队列了, 给队列中传输的每一个任务打上Id, 返回队列中取出返回之后再找到Id对于的TCS.SetResult()

http://www.auto-trainer.com/atricle/d0e76007.html
http://www.auto-trainer.com/atricle/c2cf999e.html
http://www.auto-trainer.com/atricle/b276eb1a.html
http://www.auto-trainer.com/atricle/c5523595.html
http://www.auto-trainer.com/atricle/08f72770.html
http://www.auto-trainer.com/atricle/2408a9e8.html
http://www.auto-trainer.com/atricle/698c85ac.html
http://www.auto-trainer.com/atricle/f3dcc41e.html
http://www.auto-trainer.com/atricle/6715100f.html
http://www.auto-trainer.com/atricle/731c9d69.html
http://www.auto-trainer.com/atricle/f5af80d5.html
http://www.auto-trainer.com/atricle/aaa222bf.html
http://www.auto-trainer.com/atricle/27d4f2ab.html
http://www.auto-trainer.com/atricle/56e8629e.html
http://www.auto-trainer.com/atricle/102b932b.html
http://www.auto-trainer.com/atricle/77c37c09.html
http://www.auto-trainer.com/atricle/eeb32434.html
http://www.auto-trainer.com/atricle/2a0ae7c1.html
http://www.auto-trainer.com/atricle/d206ffd0.html
http://www.auto-trainer.com/atricle/5969acbc.html
http://www.auto-trainer.com/atricle/b5a49894.html
http://www.auto-trainer.com/atricle/1baf132f.html
http://www.auto-trainer.com/atricle/7bee1503.html
http://www.auto-trainer.com/atricle/567df57f.html
http://www.auto-trainer.com/atricle/ade485d5.html
http://www.auto-trainer.com/atricle/0b752042.html
http://www.auto-trainer.com/atricle/25bce1ee.html
http://www.auto-trainer.com/atricle/8b6f63ed.html
http://www.auto-trainer.com/atricle/9bfa653b.html
http://www.auto-trainer.com/atricle/d258f9e6.html
http://www.auto-trainer.com/atricle/4cbe000b.html
http://www.auto-trainer.com/atricle/290f15fd.html
http://www.auto-trainer.com/atricle/1588576f.html
http://www.auto-trainer.com/atricle/62270b93.html
http://www.auto-trainer.com/atricle/e14966c5.html
http://www.auto-trainer.com/atricle/c629e385.html
http://www.auto-trainer.com/atricle/64ccf957.html
http://www.auto-trainer.com/atricle/0dd02223.html
http://www.auto-trainer.com/atricle/1f978642.html
http://www.auto-trainer.com/atricle/2f60eae3.html
http://www.auto-trainer.com/atricle/67362cf6.html
http://www.auto-trainer.com/atricle/c9096ddd.html
http://www.auto-trainer.com/atricle/e799d4e6.html
http://www.auto-trainer.com/atricle/4e817308.html
http://www.auto-trainer.com/atricle/20b63d10.html
http://www.auto-trainer.com/atricle/4d4230b1.html
http://www.auto-trainer.com/atricle/9ff9a042.html
http://www.auto-trainer.com/atricle/65304d31.html
http://www.auto-trainer.com/atricle/455d4124.html
http://www.auto-trainer.com/atricle/546b4aef.html
http://www.auto-trainer.com/atricle/a7fb979d.html
http://www.auto-trainer.com/atricle/a58afce4.html
http://www.auto-trainer.com/atricle/e7bb788e.html
http://www.auto-trainer.com/atricle/4e63944e.html
http://www.auto-trainer.com/atricle/a969cfe3.html
http://www.auto-trainer.com/atricle/a1737a07.html
http://www.auto-trainer.com/atricle/c0f78f4f.html
http://www.auto-trainer.com/atricle/30e41463.html
http://www.auto-trainer.com/atricle/84ad619d.html
http://www.auto-trainer.com/atricle/706db883.html
http://www.auto-trainer.com/atricle/b9fa0475.html
http://www.auto-trainer.com/atricle/1c547317.html
http://www.auto-trainer.com/atricle/e688ddfa.html
http://www.auto-trainer.com/atricle/45773516.html
http://www.auto-trainer.com/atricle/45d2cbe1.html
http://www.auto-trainer.com/atricle/50421d28.html
http://www.auto-trainer.com/atricle/78385d28.html
http://www.auto-trainer.com/atricle/540d6101.html
http://www.auto-trainer.com/atricle/31971dfb.html
http://www.ajzmzp.com/atricle/a7c2659a.html
http://www.ajzmzp.com/atricle/6dfc286d.html
http://www.ajzmzp.com/atricle/3610d942.html
http://www.ajzmzp.com/atricle/aa9ebb59.html
http://www.ajzmzp.com/atricle/4b9019a9.html
http://www.ajzmzp.com/atricle/c74052ee.html
http://www.ajzmzp.com/atricle/ebe657e3.html
http://www.ajzmzp.com/atricle/a597e1bc.html
http://www.ajzmzp.com/atricle/dfd1aa58.html
http://www.ajzmzp.com/atricle/83ea6c3e.html
http://www.ajzmzp.com/atricle/daf2531f.html
http://www.ajzmzp.com/atricle/8b7be6e9.html
http://www.ajzmzp.com/atricle/d26f4c0d.html
http://www.ajzmzp.com/atricle/effe9900.html
http://www.ajzmzp.com/atricle/4b403adb.html
http://www.ajzmzp.com/atricle/9ae4949c.html
http://www.ajzmzp.com/atricle/218abf15.html
http://www.ajzmzp.com/atricle/3e721879.html
http://www.ajzmzp.com/atricle/e6dc8d88.html
http://www.ajzmzp.com/atricle/319a73d9.html
http://www.ajzmzp.com/atricle/69dc781c.html
http://www.ajzmzp.com/atricle/b94a8a17.html
http://www.ajzmzp.com/atricle/5589dd72.html
http://www.ajzmzp.com/atricle/6ab5b7cc.html
http://www.ajzmzp.com/atricle/26b405bc.html
http://www.ajzmzp.com/atricle/3f4169d9.html
http://www.ajzmzp.com/atricle/68bd8cd9.html
http://www.ajzmzp.com/atricle/f14406f8.html
http://www.ajzmzp.com/atricle/a265645e.html
http://www.ajzmzp.com/atricle/b7db135e.html
http://www.ajzmzp.com/atricle/8308b5f9.html
http://www.ajzmzp.com/atricle/638668ae.html
http://www.ajzmzp.com/atricle/b6d3ffc9.html
http://www.ajzmzp.com/atricle/8b726449.html
http://www.ajzmzp.com/atricle/acf0ef38.html
http://www.ajzmzp.com/atricle/8d3be96a.html
http://www.ajzmzp.com/atricle/c0dd2ce3.html
http://www.ajzmzp.com/atricle/912cfdc9.html
http://www.ajzmzp.com/atricle/493f3594.html
http://www.ajzmzp.com/atricle/bc171e84.html
http://www.ajzmzp.com/atricle/bc7fddd6.html
http://www.ajzmzp.com/atricle/f13e276f.html
http://www.ajzmzp.com/atricle/b8a276ec.html
http://www.ajzmzp.com/atricle/dd6e4072.html
http://www.ajzmzp.com/atricle/885320cb.html
http://www.ajzmzp.com/atricle/6083dbc0.html
http://www.ajzmzp.com/atricle/deac337f.html
http://www.ajzmzp.com/atricle/850b8d89.html
http://www.ajzmzp.com/atricle/4aa46859.html
http://www.ajzmzp.com/atricle/a893234a.html
http://www.ajzmzp.com/atricle/b11a2428.html
http://www.ajzmzp.com/atricle/60f6eafe.html
http://www.czctt.com/atricle/0cbb9162.html
http://www.czctt.com/atricle/a6034940.html
http://www.czctt.com/atricle/b2b10a99.html
http://www.czctt.com/atricle/725fd032.html
http://www.czctt.com/atricle/f670782f.html
http://www.czctt.com/atricle/378e8010.html
http://www.czctt.com/atricle/2d9af51d.html
http://www.czctt.com/atricle/618d63e9.html
http://www.czctt.com/atricle/bd3ae203.html
http://www.czctt.com/atricle/b0e01434.html
http://www.czctt.com/atricle/6a09e373.html
http://www.czctt.com/atricle/17a98faa.html
http://www.czctt.com/atricle/2afe5e28.html
http://www.czctt.com/atricle/03d8734a.html
http://www.czctt.com/atricle/068b294e.html
http://www.czctt.com/atricle/02c62305.html
http://www.czctt.com/atricle/32dbf632.html
http://www.czctt.com/atricle/e0edeaf2.html
http://www.czctt.com/atricle/5b023c54.html
http://www.czctt.com/atricle/b8093c9b.html
http://www.czctt.com/atricle/d8b6836c.html
http://www.czctt.com/atricle/21b78ced.html
http://www.czctt.com/atricle/961fc240.html
http://www.czctt.com/atricle/e0da7c33.html
http://www.czctt.com/atricle/5e2c9efd.html
http://www.czctt.com/atricle/f3ebd6fb.html
http://www.czctt.com/atricle/58157668.html
http://www.czctt.com/atricle/d5616bc9.html
http://www.czctt.com/atricle/35c97dba.html
http://www.czctt.com/atricle/42dde8fb.html
http://www.czctt.com/atricle/bc1b0846.html
http://www.czctt.com/atricle/fa279dbc.html
http://www.czctt.com/atricle/6ddacae8.html
http://www.czctt.com/atricle/c6c6c9a9.html
http://www.czctt.com/atricle/45c0f868.html
http://www.czctt.com/atricle/1714c449.html
http://www.czctt.com/atricle/df44a11a.html
http://www.czctt.com/atricle/924d41f9.html
http://www.czctt.com/atricle/8f5f6889.html
http://www.czctt.com/atricle/7e917718.html
http://www.czctt.com/atricle/b22cfadf.html
http://www.czctt.com/atricle/0e2c316b.html
http://www.czctt.com/atricle/eb5ac9f7.html
http://www.czctt.com/atricle/5aba50c4.html
http://www.czctt.com/atricle/198f1676.html
http://www.czctt.com/atricle/54e63d45.html
http://www.czctt.com/atricle/9c932ddc.html
http://www.czctt.com/atricle/8d5c4453.html
http://www.czctt.com/atricle/9363a552.html
http://www.czctt.com/atricle/8393c148.html
http://www.czctt.com/atricle/57fd604f.html
http://www.czctt.com/atricle/514d37fe.html
http://www.czctt.com/atricle/042a6cd5.html
http://www.czctt.com/atricle/14202072.html
http://www.czctt.com/atricle/b1ce9bc4.html
http://www.czctt.com/atricle/0d662ddb.html
http://www.czctt.com/atricle/2f5751f4.html
http://www.czctt.com/atricle/544d6daf.html
http://www.czctt.com/atricle/1555dff0.html
http://www.czctt.com/atricle/b0e45d8f.html
http://www.czctt.com/atricle/0d374519.html
http://www.czctt.com/atricle/8e436877.html
http://www.ajzmzp.com/atricle/e97f3683.html
http://www.ajzmzp.com/atricle/ffd6f2df.html
http://www.ajzmzp.com/atricle/2ac4c279.html
http://www.ajzmzp.com/atricle/8143df08.html
http://www.ajzmzp.com/atricle/34905b54.html
http://www.ajzmzp.com/atricle/19f36008.html
http://www.ajzmzp.com/atricle/99b5702e.html
http://www.ajzmzp.com/atricle/0ed53e27.html
http://www.ajzmzp.com/atricle/febc1a83.html
http://www.ajzmzp.com/atricle/5e4dd7e6.html
http://www.ajzmzp.com/atricle/d7c9cc49.html
http://www.ajzmzp.com/atricle/52600c2c.html
http://www.ajzmzp.com/atricle/cac8a2ad.html
http://www.ajzmzp.com/atricle/25b63512.html
http://www.ajzmzp.com/atricle/06b3646e.html
http://www.ajzmzp.com/atricle/0a6ae156.html
http://www.ajzmzp.com/atricle/82fde4f7.html
http://www.ajzmzp.com/atricle/3090d061.html
http://www.ajzmzp.com/atricle/1e0cc16a.html
http://www.ajzmzp.com/atricle/8540093d.html
http://www.ajzmzp.com/atricle/376c595c.html
http://www.ajzmzp.com/atricle/792c17f4.html
http://www.ajzmzp.com/atricle/2485f922.html
http://www.ajzmzp.com/atricle/5d797d0f.html
http://www.ajzmzp.com/atricle/2b057b32.html
http://www.ajzmzp.com/atricle/735f685c.html
http://www.ajzmzp.com/atricle/a588a35e.html
http://www.ajzmzp.com/atricle/03c95da0.html
http://www.ajzmzp.com/atricle/1935b380.html
http://www.ajzmzp.com/atricle/98602f8b.html
http://www.ajzmzp.com/atricle/1d27c4e7.html
http://www.ajzmzp.com/atricle/37e49dbe.html
http://www.ajzmzp.com/atricle/6bcd420d.html
http://www.ajzmzp.com/atricle/15d8bea6.html
http://www.ajzmzp.com/atricle/1e0d496a.html
http://www.ajzmzp.com/atricle/7520b6ad.html
http://www.ajzmzp.com/atricle/82d52738.html
http://www.ajzmzp.com/atricle/9e3ab79a.html
http://www.ajzmzp.com/atricle/b9785b74.html
http://www.ajzmzp.com/atricle/0328669f.html
http://www.ajzmzp.com/atricle/7252a87a.html
http://www.ajzmzp.com/atricle/a422956f.html
http://www.ajzmzp.com/atricle/2b9a23eb.html
http://www.ajzmzp.com/atricle/a92e3bcb.html
http://www.ajzmzp.com/atricle/cac6c142.html
http://www.ajzmzp.com/atricle/269ef63c.html
http://www.ajzmzp.com/atricle/99f7e525.html
http://www.ajzmzp.com/atricle/d5be903e.html
http://www.ajzmzp.com/atricle/d5ac2e45.html
http://www.ajzmzp.com/atricle/ddf9fa59.html
http://www.ajzmzp.com/atricle/45a00d57.html
http://www.ajzmzp.com/atricle/3b6f605e.html
http://www.ajzmzp.com/atricle/84898a90.html
http://www.ajzmzp.com/atricle/9ed0f431.html
http://www.ajzmzp.com/atricle/eaadf9ed.html
http://www.ajzmzp.com/atricle/7a863db1.html
http://www.ajzmzp.com/atricle/7e3a0dae.html
http://www.ajzmzp.com/atricle/678cc0e8.html
http://www.ajzmzp.com/atricle/f2e9ed06.html
http://www.ajzmzp.com/atricle/79f31673.html
http://www.ajzmzp.com/atricle/6b0f30ba.html
http://www.ajzmzp.com/atricle/61fbc443.html
http://www.ajzmzp.com/atricle/7c9dbba4.html
http://www.ajzmzp.com/atricle/a19a6a24.html
http://www.ajzmzp.com/atricle/60e9e865.html
http://www.ajzmzp.com/atricle/af27ce13.html
http://www.ajzmzp.com/atricle/468f3d2c.html
http://www.ajzmzp.com/atricle/fe39e394.html
http://www.ajzmzp.com/atricle/ba3cf6c2.html
http://www.72177.com/htm/201912/08/4509734.htm
http://www.72177.com/htm/201912/08/4509731.htm
http://www.72177.com/htm/201912/08/4509729.htm
http://www.72177.com/htm/201912/08/4509727.htm
http://www.72177.com/htm/201912/08/4509725.htm
http://www.72177.com/htm/201912/08/4509722.htm
http://www.72177.com/htm/201912/08/4509720.htm
http://www.72177.com/htm/201912/08/4509718.htm
http://www.72177.com/htm/201912/08/4509715.htm
http://www.72177.com/htm/201912/08/4509714.htm
http://www.72177.com/htm/201912/08/4509713.htm
http://www.72177.com/htm/201912/08/4509712.htm
http://www.72177.com/htm/201912/08/4509711.htm
http://www.72177.com/htm/201912/08/4509710.htm
http://www.72177.com/htm/201912/08/4509709.htm
http://www.72177.com/htm/201912/08/4509708.htm
http://www.72177.com/htm/201912/08/4509707.htm
http://www.72177.com/htm/201912/08/4509706.htm
http://www.72177.com/htm/201912/08/4509705.htm
http://www.72177.com/htm/201912/08/4509704.htm
http://www.72177.com/htm/201912/08/4509703.htm
http://www.72177.com/htm/201912/08/4509702.htm
http://www.72177.com/htm/201912/08/4509701.htm
http://www.72177.com/htm/201912/08/4509700.htm
http://market.szonline.net/amaz/27752.html
http://market.szonline.net/amaz/27748.html
http://market.szonline.net/amaz/27745.html
http://market.szonline.net/amaz/27741.html
http://market.szonline.net/amaz/27738.html
http://market.szonline.net/amaz/27734.html
http://market.szonline.net/amaz/27733.html
http://market.szonline.net/amaz/27732.html
http://market.szonline.net/amaz/27731.html
http://market.szonline.net/amaz/27730.html
http://market.szonline.net/amaz/27729.html
http://market.szonline.net/amaz/27728.html
http://market.szonline.net/amaz/27727.html
http://market.szonline.net/amaz/27726.html
http://market.szonline.net/amaz/27725.html
http://market.szonline.net/amaz/27724.html
http://market.szonline.net/amaz/27723.html
http://market.szonline.net/amaz/27722.html
http://market.szonline.net/amaz/27721.html
http://market.szonline.net/amaz/27720.html
http://market.szonline.net/amaz/27719.html
http://market.szonline.net/amaz/27718.html
http://market.szonline.net/amaz/27717.html
http://market.szonline.net/amaz/27716.html
http://market.szonline.net/amaz/27715.html
http://market.szonline.net/amaz/27714.html
http://market.szonline.net/amaz/27713.html
http://market.szonline.net/amaz/27712.html

标签:异步,www,ajzmzp,C#,atricle,案例,auto,com,htmlhttp
来源: https://www.cnblogs.com/cider/p/12004976.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有