在我的 TPL 应用程序中,我想通过方法 PlayTTS(string text)
播放文本到语音。
public static CancellationTokenSource cTokenSource = new CancellationTokenSource();
public static CancellationToken cToken = cTokenSource.Token;
然后在消费者方法中。
async Task Consumer()
{
try
{
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 50,
CancellationToken = cToken
};
var consumerBlock = new ActionBlock<AppointmentReminder>(
remainder =>
{
if (cToken.IsCancellationRequested)
return;
Dictionary<string, string> dict = new OutboundDial(ts).RunScript(remainder, cToken);
// update UI by the returned dictionary
},
executionDataflowBlockOptions);
m_bufferBlock.LinkTo(
consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });
await consumerBlock.Completion;
}
我有一个按钮事件来取消进程(WPF)。
private void Cancel_Click(object sender, RoutedEventArgs e)
{
cTokenSource.Cancel();
}
您看到 ActionBlock
中有 cToken.IsCancellationRequested
,但是它并没有帮助停止方法 OutboundDial(ts).RunScript(剩余部分,cToken);
虽然我传入了取消 token 。
现在让我们看看RunScript
方法。
public Dictionary<string, string> RunScript(AppointmentReminder callData, CancellationToken cToken)
{
try
{
m_ChannelResource = m_TelephonyServer.GetChannel() as SipChannel;
m_VoiceResource = m_ChannelResource.VoiceResource;
// Many logging
// Dial out
MakeTest(callData, cToken);
}
catch
{throw;}
finally
{
// destroy m_ChannelResource and m_VoiceResource
}
return dict;
}
关键点是方法MakeTest
,里面有PlayTTS
;
public void MakeTest(AppointmentReminder callData, CancellationToken cToken)
{
try
{
if (!cToken.IsCancellationRequested)
{
m_VoiceResource.PlayTTS(callData.Text);
}
else
{
cToken.ThrowIfCancellationRequested();
m_VoiceResource.Stop(); // Stops any current activity on m_VoiceResource.
dict["ConnectedTime"] = " no connection";
dict["DialingResult"] = " cancellation";
}
当我单击取消按钮时,我当前的代码未到达 m_VoiceResource.Stop()
部分。
所以我的问题是当cTokenSource.Cancel();
时,如何让代码运行在:
m_VoiceResource.Stop(); // Stops any current activity on m_VoiceResource.
dict["ConnectedTime"] = " no connection";
dict["DialingResult"] = " cancellation";
编辑:2014 年 10 月 31 日下午 1:10
根据Servy的评论,我使用了cToken.Register(() => m_VoiceResource.Stop());
我在 OneDrive 创建了一个类似的演示。
最佳答案
在检查 token 是否已取消并开始播放后,您将取消 token 。你永远不会回去并再次执行该条件来停止。
您需要做的只是注册一个回调来取消 token 以停止玩家:
cToken.Register(() => m_VoiceResource.Stop());
只需在开始玩游戏后立即添加该注册即可。
关于c# - 如何在 TPL 中停止播放并返回正确的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26633533/