鉴于取消令牌,我想创建一个等待它的任务,这是永远不会完成但可以取消。我需要这样的模式,IMO应该很常见:
async Task DoStuff(Task t, CancellationToken ct)
{
// t was made from TaskCompletionSource,
// both t and ct are beyond my control
Task t2 = TaskFromCancellationToken(ct);
await Task.WhenAny(t, t2);
// do stuff
}
我到目前为止最好的想法是:
Task TaskFromCancelationToken(CancellationToken ct)
{
return Task.Delay(Timeout.Infinite, ct);
}
有没有更好的方法来实现这种逻辑?
答案 0 :(得分:18)
它不是非常常见,但它足以成为我的AsyncEx库的一部分。我使用something like这个:
public static Task AsTask(this CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<object>();
cancellationToken.Register(() => tcs.TrySetCanceled(),
useSynchronizationContext: false);
return tcs.Task;
}
答案 1 :(得分:9)
Task.Delay(Timeout.Infinite, cancellationToken)
您在问题中建议的答案是我所知道的最佳解决方案。原因如下:
根据我的知识,很多人都大量使用Task.Delay
方法,并且在Microsoft博客上也推荐使用TaskCompletionSource
方法。 MSDN Example
为什么要自己编写代码(包括测试)来利用function myLogger(logString) {
alert("Inside mylogger");
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
alert("Inside Local File System");
var absPath = cordova.file.externalRootDirectory;
var fileDir = cordova.file.externalDataDirectory.replace(cordova.file.externalRootDirectory, '');
var fileName = "logfile.txt";
var filePath = fileDir + fileName;
alert(filePath);
fs.root.getFile(filePath, {create: true, exclusive: false}, function (fileEntry) {
alert("Inside getFile method");
fileEntry.createWriter(function (fileWriter) {
alert("Inside createwriter method");
fileWriter.seek(fileWriter.length); // Start write position at EOF.
var logStringWithTimeStamp = Date.parse(new Date()) + " : " + logString + "\n";
var blob = new Blob([logStringWithTimeStamp], {type: 'text/plain', endings: 'native'});
fileWriter.write(blob);
}, function (err) {
console.log("Err logString" + err);
});
}, function (err) {
console.log("Err" + err);
});
}, function (err) {
console.log("Err1" + err);
});
}
myLogger("Hello Logger");
将取消令牌转换为任务?最好是利用标准库而不是重新发明轮子;它们比你的代码更容易出错。