Разница между асинхронными методами на основе событий и на основе обратных вызовов / делегатов? - PullRequest
4 голосов
/ 30 января 2009

При использовании svcutil.exe я заметил этот ключ / tcv: Version35. Документы говорят это:

Version35: используйте / tcv: Version35, если вы генерируют код для клиентов, которые использовать .NET Framework 3.5. Используя это значение, инструмент SvcUtil.exe генерирует код, который ссылается на функциональность в .NET Framework 3.5 и более ранние версии версии. При использовании / tcv: Version35 с ключом / async оба основанный на событиях и обратный вызов / основанный на делегате асинхронный методы генерируются. К тому же, поддержка наборов данных с поддержкой LINQ и DateTimeOffset включен.

В чем разница между асинхронными моделями на основе событий и обратного вызова / делегата?

РЕДАКТИРОВАТЬ: Один способ новее / лучше? Я получаю методы BeginXXX и EndXXX только тогда, когда не использую ключ / tcv: Version35. Silverlight использует XXXAsync, который говорит мне, что я должен использовать методы, основанные на событиях (XXXAsync), и использовать этот переключатель.

1 Ответ

2 голосов
/ 30 января 2009

Давайте определим сервис WCF следующим образом:

namespace StackOverflow
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string GetName();
    }

    public class Test : ITest
    {
        public string GetName()
        {
            return "Joel Spolsky";
        }
    }
}

Если вы запустите svcutil для этого, вы получите следующее определение клиента:

public partial class TestClient : System.ServiceModel.ClientBase<ITest>, ITest
{
    // Other details elided...    

    public string GetData(int value)
    {
        return base.Channel.GetData(value);
    }
}

Если вы снова запустите svcutil с использованием флага / async, вы получите следующее определение клиента:

public partial class TestClient : System.ServiceModel.ClientBase<ITest>, ITest
{
    // Other details elided...

    public event System.EventHandler<GetDataCompletedEventArgs> GetDataCompleted;

    public string GetData(int value)
    {
        return base.Channel.GetData(value);
    }

    [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
    public System.IAsyncResult BeginGetData(int value, System.AsyncCallback callback, object asyncState)
    {
        return base.Channel.BeginGetData(value, callback, asyncState);
    }

    [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
    public string EndGetData(System.IAsyncResult result)
    {
        return base.Channel.EndGetData(result);
    }

    public void GetDataAsync(int value, object userState)
    {
        if ((this.onBeginGetDataDelegate == null))
        {
            this.onBeginGetDataDelegate = new BeginOperationDelegate(this.OnBeginGetData);
        }
        if ((this.onEndGetDataDelegate == null))
        {
            this.onEndGetDataDelegate = new EndOperationDelegate(this.OnEndGetData);
        }
        if ((this.onGetDataCompletedDelegate == null))
        {
            this.onGetDataCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnGetDataCompleted);
        }
        base.InvokeAsync(this.onBeginGetDataDelegate, new object[] {value}, this.onEndGetDataDelegate, this.onGetDataCompletedDelegate, userState);
    }
}

Таким образом, флаг / async просто дает вам возможность асинхронно взаимодействовать с вашим сервисом вместо поведения по умолчанию только синхронно.

Метод GetDataAsync () вызывает метод GetData () асинхронно и уведомляет вас о завершении через событие GetDataCompleted.

Методы BeginGetData () и EndGetData () используют асинхронное поведение делегатов для асинхронного вызова метода GetData (). Это аналогично методам BeginInvoke () и EndInvoke () в классе System.Windows.Forms.Control или методам BeginRead () и EndRead () в классе System.IO.Stream.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...