【发布时间】:2014-03-07 17:02:38
【问题描述】:
我有一个位于 Task.Run() 下的方法 HandleAcceptedConnection,我想异步运行(在另一个单独的线程中)。我尝试将 HandleAcceptedConnection 声明为异步方法并且不调用 await 但它似乎没有异步运行。我可以确认我可以在另一个 Task.Run() 下拥有 Task.Run()(通过查看线程 id),但这是推荐的吗?
private async void Start_Click(object sender, RoutedEventArgs e)
{
var task = Task.Run(() =>
{
while (isContinue)
{
var handler = listener.Accept();
// handle connection
Log("Before");
Log("ThreadId Accept " + Thread.CurrentThread.ManagedThreadId);
// i want to run method below asynchronously. i want to
// wrap it under Task.Run() but i am already under
// Task.Run(). i set HandleAcceptedConnection as async. i thought by not
// calling await on HandleAcceptedConnection, HandleAcceptedConnection
// is asynchronous
HandleAcceptedConnection(handler);
Log("After");
isContinue = true;
}
});
await task;
}
private async Task HandleAcceptedConnection(Socket handler)
{
Log("ThreadId HandleAcceptedConnection " + Thread.CurrentThread.ManagedThreadId);
Log("Under HandleAcceptedConnection");
Thread.Sleep(10000);
}
当我运行它时,日志说
Before
Under HandleAcceptedConnection
After
我想要
Before
After
Under HandleAcceptedConnection
我希望 HandleAcceptedConnection 异步运行。我应该将它包装在另一个 Task.Run 下还是它已经是异步的?
【问题讨论】:
-
您的方法将同步运行,因为它不包含
await语句。但即使它确实异步运行,这也意味着您根本无法保证“After”和“Under”会出现在哪个顺序。如果您需要 “After”出现在“Under”之前,只需将方法调用移动到末尾即可。您想在这里实现什么目标? -
我认为您需要更深入地阅读 async/await/Tasks。主要要理解:async/await/Task 不一定等于多线程。
-
@Jon "Before" "after" "Under" 只是指定 HandleAcceptedConnection 是同步运行还是异步运行。了解 HandleAcceptedConnection 是否异步运行的更好方法是监视线程(我刚刚添加)。我想要的只是在“上面的调用者”的另一个线程/异步中运行 HandleAcceptedConnection。
-
@publicENEMY 现在将
Thread.Sleep(10000);替换为await Task.Delay(10000);并重试。顺便说一句:在 Logging 之前使用它可以看到它会在 afterLog("after")运行 -
@L.B 做到了。我还在 Task.Delay() 之前和之后放置了 Thread.CurrentThread.ManagedThreadId ,并且似乎在 Task.Delay() 之前和之后使用了不同的线程。似乎 Task.Delay() 导致该方法使用不同的线程。
标签: c# multithreading asynchronous task-parallel-library