dotnetty 新的篇章- 开源
<h2>一、前言</h2><p> 因为微服务引擎依赖于dotnetty组件,很多协议都是针对于dotnetty 进行扩展,然后对于老版本https://github.com/azure/dotnetty 停止更新后,本人下载源码进行修改更新,并且大家要求独立仓库进行开源,所以今天整理了代码开源至https://github.com/microsurging/DotNetty, 也希望大家一起贡献代码,让dotnetty 生态更强大。</p>
<p>HttpFlv:http://demo.kayakiot.cn:281/httpflv.html (黑衣人)</p>
<p> HttpFlv:http://demo.kayakiot.cn:281/httpflv1.html (大红包)</p>
<p>HttpFlv:http://demo.kayakiot.cn:281/httpflv2.html (鹿鼎记)</p>
<p>rtmp:rtmp://demo.kayakiot.cn:76/live1/livestream2 (黑衣人)</p>
<p>rtmp:rtmp://demo.kayakiot.cn:76/live1/livestream3 (大红包)</p>
<p>rtmp:rtmp://demo.kayakiot.cn:76/live1/livestream4(鹿鼎记)</p>
<p>注:测试服务器带宽只有8MB, httpflv 缓冲做的没有rtmp好,然后httpflv卡就多刷新几次</p>
<p> 凯亚 (Kayak) 是什么?</p>
<p> 凯亚(Kayak)是基于.NET8.0软件环境下的surging微服务引擎进行开发的, 平台包含了微服务和物联网平台。支持异步和响应式编程开发,功能包含了物模型,设备,产品,网络组件的统一管理和微服务平台下的注册中心,服务路由,模块,中间服务等管理。还有多协议适配(TCP,MQTT,UDP,CoAP,HTTP,Grpc,websocket,rtmp,httpflv,webservice,等),通过灵活多样的配置适配能够接入不同厂家不同协议等设备。并且通过设备告警,消息通知,数据可视化等功能。能够让你能快速建立起微服务物联网平台系统。</p>
<p> 凯亚物联网平台:http://demo.kayakiot.cn:3100(用户名:fanly 密码:123456)</p>
<p> 链路跟踪Skywalking V8:http://117.72.121.2:8080/</p>
<p> surging 微服务引擎开源地址:https://github.com/fanliang11/surging(后面surging 会移动到microsurging进行维护)</p>
<h2>二、ValueTask扩展支持</h2>
<p>IValueTaskPromise:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IValueTaskPromise: IPromise
{
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsVoid { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsCompleted { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsSuccess { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsFaulted { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsCanceled { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TryComplete();
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Complete();
</span><span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TrySetException(Exception exception);
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> TrySetException(IEnumerable<Exception><span style="color: rgba(0, 0, 0, 1)"> exceptions);
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetException(Exception exception);
</span><span style="color: rgba(0, 0, 255, 1)">void</span> SetException(IEnumerable<Exception><span style="color: rgba(0, 0, 0, 1)"> exceptions);
</span><span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TrySetCanceled();
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetCanceled();
</span><span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> SetUncancellable();
IPromise Unvoid();
}</span></pre>
</div>
<p>DefaultValueTaskPromise:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> DefaultValueTaskPromise: IValueTaskPromise
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> CancellationToken _token;
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> NET
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> TaskCompletionSource _tcs;
</span><span style="color: rgba(0, 0, 255, 1)">#else</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> ManualResetValueTaskSource<<span style="color: rgba(0, 0, 255, 1)">object</span>><span style="color: rgba(0, 0, 0, 1)"> _tcs;
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> v_uncancellable =<span style="color: rgba(0, 0, 0, 1)"> SharedConstants.False;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DefaultValueTaskPromise()
{
_token </span>=<span style="color: rgba(0, 0, 0, 1)"> CancellationToken.None;
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> NET<span style="color: rgba(0, 0, 0, 1)">
_tcs </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TaskCompletionSource();
</span><span style="color: rgba(0, 0, 255, 1)">#else</span><span style="color: rgba(0, 0, 0, 1)">
_tcs </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ManualResetValueTaskSource<<span style="color: rgba(0, 0, 255, 1)">object</span>><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> DefaultValueTaskPromise(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> state)
{
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> NET<span style="color: rgba(0, 0, 0, 1)">
_tcs </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TaskCompletionSource(state);
</span><span style="color: rgba(0, 0, 255, 1)">#else</span><span style="color: rgba(0, 0, 0, 1)">
_tcs </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ManualResetValueTaskSource<<span style="color: rgba(0, 0, 255, 1)">object</span>><span style="color: rgba(0, 0, 0, 1)">(state);
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DefaultValueTaskPromise(CancellationToken cancellationToken)
{
_token</span>=<span style="color: rgba(0, 0, 0, 1)"> cancellationToken;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> ValueTask ValueTask
{
</span><span style="color: rgba(0, 0, 255, 1)">get</span> =><span style="color: rgba(0, 0, 0, 1)"> _tcs.AwaitVoid(_token);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsVoid => <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsSuccess =><span style="color: rgba(0, 0, 0, 1)"> ValueTask.IsCompletedSuccessfully;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsCompleted =><span style="color: rgba(0, 0, 0, 1)"> ValueTask.IsCompleted;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsFaulted =><span style="color: rgba(0, 0, 0, 1)"> ValueTask.IsFaulted;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsCanceled =><span style="color: rgba(0, 0, 0, 1)"> ValueTask.IsCanceled;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>TaskTask =><span style="color: rgba(0, 0, 0, 1)"> ValueTask.AsTask();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TryComplete()
{
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> NET
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _tcs.TrySetResult();
</span><span style="color: rgba(0, 0, 255, 1)">#else</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> _tcs.SetResult(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Complete()
{
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> NET<span style="color: rgba(0, 0, 0, 1)">
_tcs.SetResult();
</span><span style="color: rgba(0, 0, 255, 1)">#else</span><span style="color: rgba(0, 0, 0, 1)">
_tcs.SetResult(</span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetCanceled()
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (SharedConstants.False < (<span style="color: rgba(0, 0, 255, 1)">uint</span>)Volatile.Read(<span style="color: rgba(0, 0, 255, 1)">ref</span> v_uncancellable)) { <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">; }
_tcs.SetCanceled();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetException(Exception exception)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (exception <span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)"> AggregateException aggregateException)
{
SetException(aggregateException.InnerExceptions);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
_tcs.SetException(exception);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetException(IEnumerable<Exception><span style="color: rgba(0, 0, 0, 1)"> exceptions)
{
_tcs.SetException(exceptions.FirstOrDefault());
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TrySetCanceled()
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (SharedConstants.False < (<span style="color: rgba(0, 0, 255, 1)">uint</span>)Volatile.Read(<span style="color: rgba(0, 0, 255, 1)">ref</span> v_uncancellable)) { <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">; }
_tcs.SetCanceled();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TrySetException(Exception exception)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (exception <span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)"> AggregateException aggregateException)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> TrySetException(aggregateException.InnerExceptions);
}
_tcs.SetException(exception);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> TrySetException(IEnumerable<Exception><span style="color: rgba(0, 0, 0, 1)"> exceptions)
{
_tcs.SetException(exceptions.FirstOrDefault());
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> SetUncancellable()
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (SharedConstants.False >= (<span style="color: rgba(0, 0, 255, 1)">uint</span>)Interlocked.CompareExchange(<span style="color: rgba(0, 0, 255, 1)">ref</span><span style="color: rgba(0, 0, 0, 1)"> v_uncancellable, SharedConstants.True, SharedConstants.False))
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> !<span style="color: rgba(0, 0, 0, 1)">IsCompleted;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">string</span> ToString() => <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TaskCompletionSource</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> IPromise Unvoid() => <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>ManualResetValueTaskSource:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">interface</span> IStrongBox<T><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">ref</span> T Value { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> RunContinuationsAsynchronously { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">enum</span><span style="color: rgba(0, 0, 0, 1)"> ContinuationOptions
{
None,
ForceDefaultTaskScheduler
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> ManualResetValueTaskSource<T> : IStrongBox<ManualResetValueTaskSourceLogic<T>>, IValueTaskSource<T><span style="color: rgba(0, 0, 0, 1)">, IValueTaskSource
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> ManualResetValueTaskSourceLogic<T><span style="color: rgba(0, 0, 0, 1)"> _logic;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> Action _cancellationCallback;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ManualResetValueTaskSource(ContinuationOptions options =<span style="color: rgba(0, 0, 0, 1)"> ContinuationOptions.None)
{
_logic </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ManualResetValueTaskSourceLogic<T>(<span style="color: rgba(0, 0, 255, 1)">this</span>, options,<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
_cancellationCallback </span>=<span style="color: rgba(0, 0, 0, 1)"> SetCanceled;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ManualResetValueTaskSource(<span style="color: rgba(0, 0, 255, 1)">object</span> state, ContinuationOptions options =<span style="color: rgba(0, 0, 0, 1)"> ContinuationOptions.None)
{
_logic </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ManualResetValueTaskSourceLogic<T>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">, options,state);
_cancellationCallback </span>=<span style="color: rgba(0, 0, 0, 1)"> SetCanceled;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">short</span> Version =><span style="color: rgba(0, 0, 0, 1)"> _logic.Version;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> SetResult(T result)
{
</span><span style="color: rgba(0, 0, 255, 1)">lock</span><span style="color: rgba(0, 0, 0, 1)"> (_cancellationCallback)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (_logic.Completed)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
_logic.SetResult(result);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetException(Exception error)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Monitor.TryEnter(_cancellationCallback))
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (_logic.Completed)
{
Monitor.Exit(_cancellationCallback);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
_logic.SetException(error);
Monitor.Exit(_cancellationCallback);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetCanceled() => SetException(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TaskCanceledException());
</span><span style="color: rgba(0, 0, 255, 1)">public</span> T GetResult(<span style="color: rgba(0, 0, 255, 1)">short</span> token) =><span style="color: rgba(0, 0, 0, 1)"> _logic.GetResult(token);
</span><span style="color: rgba(0, 0, 255, 1)">void</span> IValueTaskSource.GetResult(<span style="color: rgba(0, 0, 255, 1)">short</span> token) =><span style="color: rgba(0, 0, 0, 1)"> _logic.GetResult(token);
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ValueTaskSourceStatus GetStatus(<span style="color: rgba(0, 0, 255, 1)">short</span> token) =><span style="color: rgba(0, 0, 0, 1)"> _logic.GetStatus(token);
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> RunContinuationsAsynchronously { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> OnCompleted(Action<<span style="color: rgba(0, 0, 255, 1)">object</span>> continuation, <span style="color: rgba(0, 0, 255, 1)">object</span> state, <span style="color: rgba(0, 0, 255, 1)">short</span> token, ValueTaskSourceOnCompletedFlags flags) =><span style="color: rgba(0, 0, 0, 1)"> _logic.OnCompleted(continuation, state, token, flags);
</span><span style="color: rgba(0, 0, 255, 1)">ref</span> ManualResetValueTaskSourceLogic<T> IStrongBox<ManualResetValueTaskSourceLogic<T>>.Value => <span style="color: rgba(0, 0, 255, 1)">ref</span><span style="color: rgba(0, 0, 0, 1)"> _logic;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ValueTask<T><span style="color: rgba(0, 0, 0, 1)"> AwaitValue(CancellationToken cancellation)
{
CancellationTokenRegistration</span>? registration = cancellation ==<span style="color: rgba(0, 0, 0, 1)"> CancellationToken.None
</span>? (CancellationTokenRegistration?)<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">
: cancellation.Register(_cancellationCallback);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> _logic.AwaitValue(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">, registration);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> ValueTask AwaitVoid(CancellationToken cancellation)
{
CancellationTokenRegistration</span>? registration = cancellation ==<span style="color: rgba(0, 0, 0, 1)"> CancellationToken.None
</span>? (CancellationTokenRegistration?)<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">
: cancellation.Register(_cancellationCallback);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> _logic.AwaitVoid(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">, registration);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Reset() =><span style="color: rgba(0, 0, 0, 1)"> _logic.Reset();
}
</span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">struct</span> ManualResetValueTaskSourceLogic<TResult><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> Action<<span style="color: rgba(0, 0, 255, 1)">object</span>> s_sentinel = s => <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InvalidOperationException();
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> IStrongBox<ManualResetValueTaskSourceLogic<TResult>><span style="color: rgba(0, 0, 0, 1)"> _parent;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> ContinuationOptions _options;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> Action<<span style="color: rgba(0, 0, 255, 1)">object</span>><span style="color: rgba(0, 0, 0, 1)"> _continuation;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> _continuationState;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> _capturedContext;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ExecutionContext _executionContext;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> _completed;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> TResult _result;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> ExceptionDispatchInfo _error;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationTokenRegistration?<span style="color: rgba(0, 0, 0, 1)"> _registration;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ManualResetValueTaskSourceLogic(IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent, ContinuationOptions options,<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> state)
{
_parent </span>= parent ?? <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ArgumentNullException(nameof(parent));
_options </span>=<span style="color: rgba(0, 0, 0, 1)"> options;
_continuation </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_continuationState </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_capturedContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_executionContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_completed </span>= state != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_result </span>=state==<span style="color: rgba(0, 0, 255, 1)">null</span>? <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">(TResult): (TResult)state;
_error </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
Version </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
_registration </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">short</span> Version { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Completed =><span style="color: rgba(0, 0, 0, 1)"> _completed;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ValidateToken(<span style="color: rgba(0, 0, 255, 1)">short</span><span style="color: rgba(0, 0, 0, 1)"> token)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (token !=<span style="color: rgba(0, 0, 0, 1)"> Version)
{
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InvalidOperationException();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ValueTaskSourceStatus GetStatus(<span style="color: rgba(0, 0, 255, 1)">short</span><span style="color: rgba(0, 0, 0, 1)"> token)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ValidateToken(token);</span>
<span style="color: rgba(0, 0, 255, 1)">return</span>
!_completed ?<span style="color: rgba(0, 0, 0, 1)"> ValueTaskSourceStatus.Pending :
_error </span>== <span style="color: rgba(0, 0, 255, 1)">null</span> ?<span style="color: rgba(0, 0, 0, 1)"> ValueTaskSourceStatus.Succeeded :
_error.SourceException </span><span style="color: rgba(0, 0, 255, 1)">is</span> OperationCanceledException ?<span style="color: rgba(0, 0, 0, 1)"> ValueTaskSourceStatus.Canceled :
ValueTaskSourceStatus.Faulted;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> TResult GetResult(<span style="color: rgba(0, 0, 255, 1)">short</span><span style="color: rgba(0, 0, 0, 1)"> token)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ValidateToken(token);</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">_completed)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _result;
}
TResult result </span>=<span style="color: rgba(0, 0, 0, 1)"> _result;
ExceptionDispatchInfo error </span>=<span style="color: rgba(0, 0, 0, 1)"> _error;
Reset();
error</span>?<span style="color: rgba(0, 0, 0, 1)">.Throw();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Reset()
{
Version</span>++<span style="color: rgba(0, 0, 0, 1)">;
_registration</span>?<span style="color: rgba(0, 0, 0, 1)">.Dispose();
_completed </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
_continuation </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_continuationState </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_result </span>= <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">(TResult);
_error </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_executionContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_capturedContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
_registration </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> OnCompleted(Action<<span style="color: rgba(0, 0, 255, 1)">object</span>> continuation, <span style="color: rgba(0, 0, 255, 1)">object</span> state, <span style="color: rgba(0, 0, 255, 1)">short</span><span style="color: rgba(0, 0, 0, 1)"> token, ValueTaskSourceOnCompletedFlags flags)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (continuation == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ArgumentNullException(nameof(continuation));
}
ValidateToken(token);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
_executionContext </span>=<span style="color: rgba(0, 0, 0, 1)"> ExecutionContext.Capture();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
SynchronizationContext sc </span>=<span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext.Current;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (sc != <span style="color: rgba(0, 0, 255, 1)">null</span> && sc.GetType() != <span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)">(SynchronizationContext))
{
_capturedContext </span>=<span style="color: rgba(0, 0, 0, 1)"> sc;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
TaskScheduler ts </span>=<span style="color: rgba(0, 0, 0, 1)"> TaskScheduler.Current;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ts !=<span style="color: rgba(0, 0, 0, 1)"> TaskScheduler.Default)
{
_capturedContext </span>=<span style="color: rgba(0, 0, 0, 1)"> ts;
}
}
}
_continuationState </span>=<span style="color: rgba(0, 0, 0, 1)"> state;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (Interlocked.CompareExchange(<span style="color: rgba(0, 0, 255, 1)">ref</span> _continuation, continuation, <span style="color: rgba(0, 0, 255, 1)">null</span>) != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
_executionContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">object</span> cc =<span style="color: rgba(0, 0, 0, 1)"> _capturedContext;
_capturedContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (cc)
{
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">:
Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext sc:
sc.Post(s </span>=><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> tuple = (Tuple<Action<<span style="color: rgba(0, 0, 255, 1)">object</span>>, <span style="color: rgba(0, 0, 255, 1)">object</span>><span style="color: rgba(0, 0, 0, 1)">)s;
tuple.Item1(tuple.Item2);
}, Tuple.Create(continuation, state));
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> TaskScheduler ts:
Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetResult(TResult result)
{
_result </span>=<span style="color: rgba(0, 0, 0, 1)"> result;
SignalCompletion();
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SetException(Exception error)
{
_error </span>=<span style="color: rgba(0, 0, 0, 1)"> ExceptionDispatchInfo.Capture(error);
SignalCompletion();
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SignalCompletion()
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (_completed)
{
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> InvalidOperationException(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Double completion of completion source is prohibited</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}
_completed </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (Interlocked.CompareExchange(<span style="color: rgba(0, 0, 255, 1)">ref</span> _continuation, s_sentinel, <span style="color: rgba(0, 0, 255, 1)">null</span>) != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (_executionContext != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
ExecutionContext.Run(
_executionContext,
s </span>=> ((IStrongBox<ManualResetValueTaskSourceLogic<TResult>><span style="color: rgba(0, 0, 0, 1)">)s).Value.InvokeContinuation(),
_parent </span>?? <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InvalidOperationException());
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
InvokeContinuation();
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> InvokeContinuation()
{
</span><span style="color: rgba(0, 0, 255, 1)">object</span> cc =<span style="color: rgba(0, 0, 0, 1)"> _capturedContext;
_capturedContext </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (_options ==<span style="color: rgba(0, 0, 0, 1)"> ContinuationOptions.ForceDefaultTaskScheduler)
{
cc </span>=<span style="color: rgba(0, 0, 0, 1)"> TaskScheduler.Default;
}
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (cc)
{
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (_parent.RunContinuationsAsynchronously)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> c =<span style="color: rgba(0, 0, 0, 1)"> _continuation;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (_executionContext != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
ThreadPool.QueueUserWorkItem(s </span>=><span style="color: rgba(0, 0, 0, 1)"> c(s), _continuationState);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
ThreadPool.UnsafeQueueUserWorkItem(s </span>=><span style="color: rgba(0, 0, 0, 1)"> c(s),_continuationState);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
_continuation(_continuationState);
}
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext sc:
sc.Post(s </span>=><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">ref</span> ManualResetValueTaskSourceLogic<TResult> logicRef = <span style="color: rgba(0, 0, 255, 1)">ref</span> ((IStrongBox<ManualResetValueTaskSourceLogic<TResult>><span style="color: rgba(0, 0, 0, 1)">)s).Value;
logicRef._continuation(logicRef._continuationState);
}, _parent </span>?? <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InvalidOperationException());
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> TaskScheduler ts:
Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts);
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ValueTask<T> AwaitValue<T>(IValueTaskSource<T> source, CancellationTokenRegistration?<span style="color: rgba(0, 0, 0, 1)"> registration)
{
_registration </span>=<span style="color: rgba(0, 0, 0, 1)"> registration;
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> ValueTask<T><span style="color: rgba(0, 0, 0, 1)">(source, Version);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> ValueTask AwaitVoid(IValueTaskSource source, CancellationTokenRegistration?<span style="color: rgba(0, 0, 0, 1)"> registration)
{
_registration </span>=<span style="color: rgba(0, 0, 0, 1)"> registration;
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ValueTask(source, Version);
}
}</span></pre>
</div>
<p>然后把DefaultPromise 替换成DefaultValueTaskPromise,如下图所示</p>
<p><img src="https://img2024.cnblogs.com/blog/192878/202506/192878-20250620124957180-2094341490.png"></p>
<h2>三、扩展支持rtmp编解码</h2>
<p>如下图所示 :</p>
<p><img src="https://img2024.cnblogs.com/blog/192878/202506/192878-20250620125136757-1795393625.png"></p>
<h2>四、demo展示</h2>
<p>开启了三个通道进行推流,cpu,内存都比较稳定</p>
<p><img src="https://img2024.cnblogs.com/blog/192878/202506/192878-20250620125507980-1788282642.png"></p>
<p> 在凯亚物联网平台你也可以创建rtmp组件</p>
<p><img src="https://img2024.cnblogs.com/blog/192878/202506/192878-20250620125753939-1623893860.png"></p>
<p> </p>
<p>视频中心</p>
<p><img src="https://img2024.cnblogs.com/blog/192878/202506/192878-20250620125921979-1655464165.png"></p>
<p> </p><br><br>
来源:https://www.cnblogs.com/fanliang11/p/18938169
頁:
[1]