c# - 无法获取 TaskCompletionSource 的结果
问题描述
你好我有以下问题:
我想执行类似于事务的操作。我想async
在收到外部触发器后执行一些操作。因此,我使用的TaskCompletionSource
是在表示触发器的方法中设置的 : TriggerTransaction
。 当我按下特定的控制台键时,
会在线程池中调用此触发方法。Main
在我按下A
关键字后,TriggerTransaction
执行并设置TaskCompletionSource
-s。仍然主线程不计算两个等待任务的总和。
class Program
{
public static Task<Task<int>> TransactionOperation1()
{
TaskCompletionSource<Task<int>> tcs = new TaskCompletionSource<Task<int>>();
tasks.Add(tcs);
Task<Task<int>> result = tcs.Task;
return result;
}
public static Task<Task<int>> TransactionOperation2()
{
TaskCompletionSource<Task<int>> tcs = new TaskCompletionSource<Task<int>>();
tasks.Add(tcs);
Task<Task<int>> result = tcs.Task;
return result;
}
public static async Task<int> ExecuteTransactionOnDB()
{
await Task.Delay(1000);
return 5;
}
public static async Task TriggerTransaction()
{
int value = await ExecuteTransactionOnDB();
foreach (var item in tasks)
{
item.SetResult(value);
}
}
public static List<dynamic> tasks = new List<dynamic>();
static async Task Main(string[] args)
{
Task<Task<int>> a = TransactionOperation1();
Task<Task<int>> b = TransactionOperation2();
Task.Run(async() =>
{
while (Console.ReadKey().Key != ConsoleKey.A) ;
await TriggerTransaction();
});
if (!File.Exists("D:\\data.txt"))
{
File.Create("D:\\data.txt");
}
using(FileStream stream=new FileStream("data.txt",FileMode.Append,FileAccess.Write))
{
int sum=await await a + await await b;//thread wont pass this line when tasks are set.
ReadOnlyMemory<byte> bytes = Encoding.UTF8.GetBytes(sum);
stream.Write(bytes.ToArray());
}
Console.WriteLine(await await a + await await b);
}
}
}
PS如果你想知道为什么我确实使用 aList<dynamic>
来存储TaskCompletionSource
-s ,那是因为 TransactionOperations 的返回类型会有所不同。其中一些会返回int
,其他String
.. ..etc Bool
。
为了更好地理解,我制作了一个架构-正如您将看到的那样:
-我要存储 TCS-es 的列表-
仅在设置外部触发器后才完成的某些调用(事务已执行)
您可以在 中看到Calls
,都有不同的返回类型。
解决方案
为什么你需要一个Task<Task<int>>
?简单Task<int>
就足够了,因此,TaskCompletionSource<int>
. 而且您还摆脱了尴尬await await ...
,这在您的情况下也不是必需的。
请注意,我还添加Close()
到由File.Create()
.
这是该程序的工作版本:
class Program
{
public static Task<int> TransactionOperation1()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tasks.Add(tcs);
return tcs.Task;
}
public static Task<int> TransactionOperation2()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tasks.Add(tcs);
return tcs.Task;
}
public static async Task<int> ExecuteTransactionOnDB()
{
await Task.Delay(1000);
return 5;
}
public static async Task TriggerTransaction()
{
int value = await ExecuteTransactionOnDB();
foreach (var item in tasks)
{
item.SetResult(value);
}
}
public static List<dynamic> tasks = new List<dynamic>();
static async Task Main(string[] args)
{
Task<int> a = TransactionOperation1();
Task<int> b = TransactionOperation2();
Task input = Task.Run(async () => {
while (Console.ReadKey().Key != ConsoleKey.A);
await TriggerTransaction();
});
if (!File.Exists("C:\\temp\\data.txt"))
{
File.Create("C:\\temp\\data.txt").Close();
}
using (FileStream stream = new FileStream("C:\\temp\\data.txt", FileMode.Append, FileAccess.Write))
{
int sum = await a + await b; // now it works ok
var bytes = Encoding.UTF8.GetBytes(sum.ToString());
stream.Write(bytes);
}
Console.WriteLine(await a + await b);
}
}
推荐阅读
- php - 用同一数组中的值替换数组键
- git - 詹金斯集成部分..无法将功能推送到原点
- django - 如何将更新表的数据保存到Django中的另一个表
- discord.js - 启动时弹出错误:“提供了不正确的登录详细信息”
- go - 如何有效地关闭两个 goroutine?
- f# - F#:最新 npgsql 的 SqlProvider 问题
- c# - 如何使用 LINQ / lambda 将列插入到锯齿状数组中?
- php - html / php - 使用 HTML 解析或正则表达式清理图像?
- java - BEA-101020 Servlet 因异常 java.lang.IllegalStateException 而失败
- react-native - 使用redux connect的React-native导航'无法读取未定义的属性'toString'