在wcf中阻塞和异步

时间:2014-01-15 15:23:59

标签: c# multithreading wcf asynchronous

此示例部分取自堆栈

public async Task MyMethod(string s1,sring s2)
{
    Trace.TraceInformation("info");
    //check input
    if (s1 == null || s2 == null)
        Trace.TraceInformation("error");

    Task<int> longRunningTask = LongRunningOperation();
    //indeed you can do independent to the int result work here 

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperation() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); //1 seconds delay
    return 1;
}

我希望MyMethod不会阻止。

1.这是正确的,直到Task<int> longRunningTask = LongRunningOperation();  用户被阻止了吗?我是否应该异步运行上面的代码部分(跟踪和输入检查)?如果是的话怎么样?有没有办法在没有新的异步方法实现的情况下做到这一点?

2.当我们开始时:

Task<int> longRunningTask = LongRunningOperation(); 

开始执行LongRunningOperation 在我们假设主线程(线程ID = 1)然后等待longRunningOperation时完成独立工作。

现在,如果longRunningOperation尚未完成且仍在运行,MyMethod()将返回其调用方法,因此主线程不会被阻止。当完成longRunningOperation时,来自ThreadPool的线程(可以是任何线程)将返回其先前状态的MyMethod()并继续执行(在这种情况下将结果打印到控制台)。

第二种情况是longRunningOperation已经完成执行并且结果可用。当到达await longRunningOperation时,编译器知道它有结果,并将继续在同一个线程上执行代码。 (在这种情况下打印结果到控制台)。

3.如果在异步方法期间抛出异常会发生什么?

4.如果提供了同步实现,我可以使用它吗?

1 个答案:

答案 0 :(得分:3)

1。您对代码返回给用户的位置不正确。

最多int result = await longRunningTask;的所有内容都与调用MyMethod(的函数在同一个线程上运行,而不是Task<int> longRunningTask = LongRunningOperation();调用。

如果您希望函数的同步部分也在后台线程中运行,请调用MyMethod中的Task.Run(

var myMethodTask = Task.Run(() => MyMethod("foo", "bar"));
然后,您可以await或者在返回的任务中需要的任何内容。

2。如果longRunningTask在到达await longRunningTask时完成,该函数仍将继续在同一个线程上运行,并且永远不会返回到调用者,直到它到达函数的末尾。当它到达函数的末尾时,它返回到调用者,Task已经处于完成状态。

如果longRunningTask未完成,则会在await点返回给调用者并返回Task,该Running将从Completed状态更改为{ {1}}函数完成时的状态。当await返回时,它会使用在任务开始时处于活动状态的SynchronizationContext来确定它应该继续运行的线程。如果您在点击await时在UI线程上的位置继续工作on the UI thread,默认情况下,如果没有设置SynchronizationContext,它将使用ThreadPool线程继续工作。 / p>

3。如果抛出异常,您会在await longRunningTask返回时看到异常(如果您将函数包装在Task.Run(中,则返回父线程)

4。您应该使用单独的方法进行同步实现。请参阅两篇Microsoft博客文章“Should I expose asynchronous wrappers for synchronous methods?”和“Should I expose synchronous wrappers for asynchronous methods?

相关问题