Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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#使用DataflowBlock.Completion来取消使用者任务,而不是CancellationToken_C#_Task Parallel Library_Tpl Dataflow - Fatal编程技术网

C#使用DataflowBlock.Completion来取消使用者任务,而不是CancellationToken

C#使用DataflowBlock.Completion来取消使用者任务,而不是CancellationToken,c#,task-parallel-library,tpl-dataflow,C#,Task Parallel Library,Tpl Dataflow,我想知道是否有一种简洁的方法来取代需要使用取消令牌的ReceiveAsyncIDataflowBlock.Completion或类似的方法,该方法使用BufferBlock或另一个IDataflowBlock IDataflowBlock.ReceiveAsync<T>(TimeSpan, CancellationToken) 如果InputQueue.Complete(),然后当队列清空且IDataflowBlock.Completion将变为状态RanToCompletion时

我想知道是否有一种简洁的方法来取代需要使用取消令牌的
ReceiveAsync
IDataflowBlock.Completion或类似的方法,该方法使用
BufferBlock
或另一个
IDataflowBlock

IDataflowBlock.ReceiveAsync<T>(TimeSpan, CancellationToken)
如果
InputQueue.Complete(),然后当队列清空且
IDataflowBlock.Completion
将变为状态RanToCompletion时, 可以使用
IDataflowBlock.Completion.IsCompleted
检查

如果有多个线程从队列中执行操作,则这可能发生在
InputQueue.ReceiveAsync
期间,是否有比以下更整洁的方法来处理
InputQueue
完成操作:

try
{
    String parcel = await InputQueue.ReceiveAsync(timeSpan);
}
catch(InvalidOperationException x)
{

}
最简单的方法是向块的构造函数提供令牌,如下所示:

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
,因此甚至可以取消
BufferBlock

为什么您要自己实现
Receive
逻辑?是否存在使用“否”的限制?例如,如果您的代码如下所示:

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
然后,您只需像这样使用
ActionBlock

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
var InputQueue=new BufferBlock();
变量处理程序=新动作块(地块=>
{
//句柄解析器
});
var linkOptions=newdataflowlinkoptions{PropagateCompletion=true};
LinkTo(处理程序,linkOptions);
//现在,在为InputQueue调用Complete方法后,完成操作将传播到处理程序块:
对于(int i=0;i<26;i++)
{
等待InputQueue.SendAsync(((char)(97+i)).ToString();
}
InputQueue.Complete();
等待处理者完成;
还请注意,如果您需要与UI进行一些交互,可以将最后一个块与库一起使用。

最简单的方法是向块的构造函数提供令牌,如下所示:

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
,因此甚至可以取消
BufferBlock

为什么您要自己实现
Receive
逻辑?是否存在使用“否”的限制?例如,如果您的代码如下所示:

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
然后,您只需像这样使用
ActionBlock

new ExecutionDataflowBlockOptions
{
    CancellationToken = cancellationSource.Token
});
internal void HandleMessage()
{
    try
    {
        var parcel = await InputQueue.ReceiveAsync(timeSpan);
        // handle parsel
    }
    catch(InvalidOperationException x)
    {
    }
}
var InputQueue = new BufferBlock<string>();
var Handler = new ActionBlock<string>(parcel =>
{
    // handle parsel
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
InputQueue.LinkTo(Handler, linkOptions);

// now after you call Complete method for InputQueue the completion will be propagated to your Handler block:
for (int i = 0; i < 26; i++)            
{
    await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
InputQueue.Complete();
await Handler.Completion;
var InputQueue=new BufferBlock();
变量处理程序=新动作块(地块=>
{
//句柄解析器
});
var linkOptions=newdataflowlinkoptions{PropagateCompletion=true};
LinkTo(处理程序,linkOptions);
//现在,在为InputQueue调用Complete方法后,完成操作将传播到处理程序块:
对于(int i=0;i<26;i++)
{
等待InputQueue.SendAsync(((char)(97+i)).ToString();
}
InputQueue.Complete();
等待处理者完成;

还请注意,如果您需要与UI进行一些交互,可以将最后一个块用作库。

您的示例
try catch
不是处理
完成的方式。调用
.Complete()
后,应
等待block.Completion
。你到底想做什么?此外,除非您有特定的理由需要使用
receiveasync
,否则您应该更喜欢使用
LinkTo
方法创建的块之间的链接。我有一些代码,其中许多生产者任务将数据包放在缓冲块上,许多其他任务从缓冲块读取数据包,读卡器任务有一个令牌,当没有更多生产者加载队列时通知它们。鉴于该逻辑类似于isCompleted逻辑,我希望消除对令牌的需求。我将查看链接以明确查看
LinkTo
,在
TPL数据流中,根据您的需要,您的消费任务将成为
ActionBlock
TransformBlock
。一旦它们被链接,您只需传播完成以关闭管道。您的示例
try catch
不是您处理
完成的方式。调用
.Complete()
后,应
等待block.Completion
。你到底想做什么?此外,除非您有特定的理由需要使用
receiveasync
,否则您应该更喜欢使用
LinkTo
方法创建的块之间的链接。我有一些代码,其中许多生产者任务将数据包放在缓冲块上,许多其他任务从缓冲块读取数据包,读卡器任务有一个令牌,当没有更多生产者加载队列时通知它们。鉴于该逻辑类似于isCompleted逻辑,我希望消除对令牌的需求。我将查看链接以明确查看
LinkTo
,在
TPL数据流中,根据您的需要,您的消费任务将成为
ActionBlock
TransformBlock
。一旦它们被链接,你就可以简单地传播完成来关闭管道。好了,ActionBlock是我的答案,我让消费者直接从by buffer block中获取,将其更改为:生产者提供bufferblock,bufferblock链接到action block/s。我将试验maxDegreeOfParallelism和限制用户的有界容量OK got,ActionBlock是我的答案,我让用户直接从by buffer block中获取,将其更改为:生产者提供bufferblock,bufferblock链接到action block/s。我将用maxDegreeOfParallelism和有界容量来限制用户