async Main не будет компилировать [duplicate]

Сначала я хочу исправить Грега: function abc(){} тоже облагается & mdash; имя abc определяется в области, где это определение встречается. Пример:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

Во-вторых, можно комбинировать оба стиля:

var xyz = function abc(){};

xyz будет определяться как обычно, abc не определено во всех браузеров, но Internet & nbsp; Explorer & mdash; не полагайтесь на его определение. Но он будет определен внутри своего тела:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

Если вы хотите выполнять функции псевдонима во всех браузерах, используйте этот вид объявления:

function abc(){};
var xyz = abc;

. В этом случае оба xyz и abc - это псевдонимы одного и того же объекта:

console.log(xyz === abc); // prints "true"

. Одной из основополагающих причин использования комбинированного стиля является атрибут «name» объектов функций (не поддерживаемый Internet & nbsp; Explorer). В основном, когда вы определяете функцию типа

function abc(){};
console.log(abc.name); // prints "abc"

, ее имя автоматически назначается. Но когда вы определяете его как

var abc = function(){};
console.log(abc.name); // prints ""

, его имя пуст & mdash; мы создали анонимную функцию и присвоили ей некоторую переменную.

Еще одна веская причина использовать комбинированный стиль - использовать короткое внутреннее имя для ссылки на себя, предоставляя длинное неконфликтное имя для внешних пользователей :

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

В приведенном выше примере мы можем сделать то же самое с внешним именем, но оно будет слишком громоздким (и медленнее).

(Другой способ ссылаться на себя - это использовать arguments.callee, который все еще относительно длинный и не поддерживается в строгом режиме.)

Вниз, JavaScript обрабатывает оба утверждения по-разному. Это объявление функции:

function abc(){}

abc здесь определено везде в текущей области:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

Кроме того, он поднялся с помощью инструкции return:

// We can call it here
abc(); // Works
return;
function abc(){}

Это выражение функции:

var xyz = function(){};

xyz здесь определено из точки назначения:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Объявление функции vs выражение функции является реальной причиной того, что существует разница, продемонстрированная Грегом.

Забавный факт:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Лично я предпочитаю декларацию «выражение функции», потому что таким образом я может контролировать видимость. Когда я определяю функцию, подобную

var abc = function(){};

, я знаю, что я определил функцию локально. Когда я определяю функцию, подобную

abc = function(){};

, я знаю, что я определил ее глобально, указав, что я не определял abc где-либо в цепочке областей. Этот стиль определения устойчив даже при использовании внутри eval(). Хотя определение

function abc(){};

зависит от контекста и может оставить вас гадать, где оно фактически определено, особенно в случае eval() & mdash; ответ: это зависит от браузера.

41
задан svick 23 May 2013 в 13:14
поделиться

4 ответа

Сообщение об ошибке в точности: метод Main() не может быть async, потому что, когда возвращается Main(), приложение обычно заканчивается.

Если вы хотите создать консольное приложение, которое использует async, простым решением является создание async версии Main() и синхронно Wait() по отношению к реальному Main():

static void Main()
{
    MainAsync().Wait();
}

static async Task MainAsync()
{
    // your async code here
}

Это один из редких случаев где смешение await и Wait() является хорошей идеей, вы обычно не должны этого делать.

Обновление: Async Main поддерживается в C # 7.1 .

66
ответ дан svick 21 August 2018 в 17:49
поделиться
  • 1
    wait () недействителен. как получить результат ПОСЛЕ ОЖИДАНИЯ? – Bilal Fazlani 16 July 2013 в 09:37
  • 2
    @bilalfazlani Какой результат? Main() обычно ничего не возвращает. В любом случае, если у вас есть Task<T> (т. Е. Task с результатом), вы можете использовать Result вместо Wait(). – svick 16 July 2013 в 09:50

Оберните свой асинхронный код в MainAsync() - который является асинхронной функцией, затем вызовите MainAsync().GetAwaiter().GetResult();

0
ответ дан dferenc 21 August 2018 в 17:49
поделиться

Разница между кодом в примере ссылки и вашим заключается в том, что вы пытаетесь пометить метод Main() с помощью модификатора async - это недопустимо, и ошибка говорит о том, что именно - Main() - это «точка входа» в приложение (это метод, который запускается при запуске вашего приложения), и ему не разрешено быть async.

1
ответ дан Igal Tabachnik 21 August 2018 в 17:49
поделиться
  • 1
    Как я могу вызвать метод async / await в основном методе – user 23 May 2013 в 12:05

Начиная с C # 7.1 существует 4 новых подписи для метода Main, которые позволяют сделать это async ( Источник , Источник 2 , Источник 3 ):

public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

Вы можете пометить свой метод Main ключевым словом async и использовать await внутри Main:

static async Task Main(string[] args)
{
    Task<string> getWebPageTask = GetWebPageAsync("http://msdn.microsoft.com");

    Debug.WriteLine("In startButton_Click before await");
    string webText = await getWebPageTask;
    Debug.WriteLine("Characters received: " + webText.Length.ToString()); 
}

C # 7.1 доступен в Visual Studio 2017 15.3.

9
ответ дан Roman Doskoch 21 August 2018 в 17:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: