Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 如何避免ChannelReader.WaitToReadSync时引发InvalidOperationException?_C#_Multithreading_Async Await_System.threading.channels - Fatal编程技术网

C# 如何避免ChannelReader.WaitToReadSync时引发InvalidOperationException?

C# 如何避免ChannelReader.WaitToReadSync时引发InvalidOperationException?,c#,multithreading,async-await,system.threading.channels,C#,Multithreading,Async Await,System.threading.channels,我使用System.Threading.Channel编写了异步队列。 但当我运行程序进行测试时,以下异常在随机时间抛出,工作线程停止 System.InvalidOperationException: The asynchronous operation has not completed. at System.Threading.Channels.AsyncOperation.ThrowIncompleteOperationException() at System.Thread

我使用System.Threading.Channel编写了异步队列。 但当我运行程序进行测试时,以下异常在随机时间抛出,工作线程停止

System.InvalidOperationException: The asynchronous operation has not completed.
   at System.Threading.Channels.AsyncOperation.ThrowIncompleteOperationException()
   at System.Threading.Channels.AsyncOperation`1.GetResult(Int16 token)
   at AsyncChannels.Worker() in g:\src\gitrepos\dotnet-sandbox\channelstest\AsyncChannelsTest.cs:line 26
如果捕获到异常并忽略,则代码正在工作。 但是我想消除这个错误,因为它的原因还不清楚

这是我的环境和最少的代码

  • TargetFramework=netcoreapp2.1
  • System.Threading.Channel版本=4.5.0
使用System.Threading.Channels;
使用系统线程;
使用System.Threading.Tasks;
使用制度;
使用System.Linq;
类异步通道:IDisposable
{
渠道(u渠道),;
螺纹(u螺纹),;
CancellationTokenSource\u取消;
公共频道()
{
_Channel=Channel.CreateUnbounded();
_线程=新线程(工作线程);
_Thread.Start();
_取消=新的CancellationTokenSource();
}
私人空房工人()
{
while(!\u取消。请求取消)
{
//引发System.InvalidOperationException
if(!\u Channel.Reader.waitToReadSync(\u Cancellation.Token.Result)
{
打破
}
while(_Channel.Reader.TryRead(out var项))
{
项目.TrySetResult(真);
}
}
}
公共空间处置()
{
_取消;
_Channel.Writer.TryComplete();
_Thread.Join();
}
公共任务排队()
{
var tcs=新TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
_Channel.Writer.TryWrite(tcs);
返回tcs.Task;
}
公共静态异步任务测试()
{
使用(var queue=new asynchchannels())
{
对于(int i=0;i<100000;i++)
{
wait queue.Enqueue().configurewait(false);
}
}
}
}
您喜欢这样:

_Channel.Reader.WaitToReadAsync(_Cancellation.Token).Result

使用
ValueTask
只能执行两件事:
等待它(仅一次),或者通过调用
AsTask()
将它转换为
任务。如果您需要执行任何复杂的操作,如等待
多次执行或阻塞,则需要使用
AsTask()

或者,在这种情况下,只需在标准频道消费模式中使用
wait

class AsyncChannels : IDisposable
{
  Channel<TaskCompletionSource<bool>> _Channel;
  Task _Thread;
  CancellationTokenSource _Cancellation;
  public AsyncChannels()
  {
    _Channel = Channel.CreateUnbounded<TaskCompletionSource<bool>>();
    _Thread = Task.Run(() => WorkerAsync());
    _Cancellation = new CancellationTokenSource();
  }
  private async Task WorkerAsync()
  {
    try
    {
      while (await _Channel.Reader.WaitToReadAsync(_Cancellation.Token))
        while (_Channel.Reader.TryRead(out var item))
          item.TrySetResult(true);
    }
    catch (OperationCanceledException)
    {
    }
  }
  public void Dispose()
  {
    _Cancellation.Cancel();
    _Channel.Writer.TryComplete();
  }
  ...
}
类异步通道:IDisposable
{
渠道(u渠道),;
任务线程;
CancellationTokenSource\u取消;
公共频道()
{
_Channel=Channel.CreateUnbounded();
_Thread=Task.Run(()=>WorkerAsync());
_取消=新的CancellationTokenSource();
}
专用异步任务WorkerAsync()
{
尝试
{
while(wait_Channel.Reader.WaitToReadAsync(_Cancellation.Token))
while(_Channel.Reader.TryRead(out var项))
项目.TrySetResult(真);
}
捕获(操作取消异常)
{
}
}
公共空间处置()
{
_取消;
_Channel.Writer.TryComplete();
}
...
}
您喜欢这样:

_Channel.Reader.WaitToReadAsync(_Cancellation.Token).Result

使用
ValueTask
只能执行两件事:
等待它(仅一次),或者通过调用
AsTask()
将它转换为
任务。如果您需要执行任何复杂的操作,如等待
多次执行或阻塞,则需要使用
AsTask()

或者,在这种情况下,只需在标准频道消费模式中使用
wait

class AsyncChannels : IDisposable
{
  Channel<TaskCompletionSource<bool>> _Channel;
  Task _Thread;
  CancellationTokenSource _Cancellation;
  public AsyncChannels()
  {
    _Channel = Channel.CreateUnbounded<TaskCompletionSource<bool>>();
    _Thread = Task.Run(() => WorkerAsync());
    _Cancellation = new CancellationTokenSource();
  }
  private async Task WorkerAsync()
  {
    try
    {
      while (await _Channel.Reader.WaitToReadAsync(_Cancellation.Token))
        while (_Channel.Reader.TryRead(out var item))
          item.TrySetResult(true);
    }
    catch (OperationCanceledException)
    {
    }
  }
  public void Dispose()
  {
    _Cancellation.Cancel();
    _Channel.Writer.TryComplete();
  }
  ...
}
类异步通道:IDisposable
{
渠道(u渠道),;
任务线程;
CancellationTokenSource\u取消;
公共频道()
{
_Channel=Channel.CreateUnbounded();
_Thread=Task.Run(()=>WorkerAsync());
_取消=新的CancellationTokenSource();
}
专用异步任务WorkerAsync()
{
尝试
{
while(wait_Channel.Reader.WaitToReadAsync(_Cancellation.Token))
while(_Channel.Reader.TryRead(out var项))
项目.TrySetResult(真);
}
捕获(操作取消异常)
{
}
}
公共空间处置()
{
_取消;
_Channel.Writer.TryComplete();
}
...
}

是否调试,是否确定在Dispose期间取消任务时不会出现异常?是否调试,是否确定在Dispose期间取消任务时不会出现异常?