2017-01-23 3 views
0

У меня есть асинхронная функция, работающая в фоновом режиме. Эта функция проверяет данные через TCP. У меня есть другая функция GetClientNameById, которая получит текущее значение и вернется в формате json. Тем не менее, я получаю NULL для всех значений. Как я могу прерывать посередине, получать значения и возобновлять опрос? Ниже мой код.Асинхронный с прерываниями

class Poll 
{ 
    public string A { get; set; } 
    public string B { get; set; } 
    public string C { get; set; } 
    public string D { get; set; } 
    public string E { get; set; } 
} 

public async void Polling(CancellationToken token) 
{ 
    await Task.Run(() => 
    { 
     if (token.IsCancellationRequested) 
     { 
      return; 
     } 

     while (true) 
     { 
      if (token.IsCancellationRequested) 
      { 
       return; 
      } 

      //TODO 

      poll.A = reply1; 
      poll.B = reply2; 
      poll.C = reply3; 
      poll.D = reply4; 
      poll.E = DateTime.Now.ToString("HH:mm:ss.fff"); 
     }  
    }); 
} 

Poll poll = new Poll(); 
public string GetClientNameById(string Id) 
{ 
    string json = ""; 
    if (Id == "Poll") 
    { 
     Console.WriteLine("Reply: " + poll.A + " " + poll.B + " " + poll.C + " " + poll.D + " " + poll.E); 

     json = JsonConvert.SerializeObject(poll, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }); 
    }  
    return json; 
} 
+0

Где находится переменная 'poll' и объявлена? –

+0

И вы подтвердили, что один и тот же экземпляр совместно используется функцией 'Polling' и' GetClientNameById'? Вы также подтвердили при отладке, что ваш код достигает места в «Опросе», в котором вы устанавливаете 4 свойства? И как только этот код будет достигнут и будет выполнен, вы подтвердили, что внутри 'GetClientNameById' эти 4 свойства имеют значение null? –

+0

@DarinDimitrov sry. моя вина. Я неправильно понял ваш вопрос. 'poll' объявлен выше' GetClientNameById' – active92

ответ

0

Похоже, вы звоните в Polling и GetClientNameById функции на различных экземпляров содержащего класса. Так как ваша переменная poll объявлена ​​как поле этого содержащего класса, то каждый раз будет создан новый экземпляр.

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

var myContainingClass = new MyContainingClass(); 
// Start polling 
await myContainingClass.Polling(someCancellationToken); 

// Call the GetClientNameById function on the same instance 
// on which you called the Polling function 
myContainingClass.GetClientNameById("Poll"); 
myContainingClass.GetClientNameById("Poll"); 
myContainingClass.GetClientNameById("Poll"); 
... 

Также есть гоночная состояние в вашем коде. Поскольку внутри вашей функции опроса у вас есть 4 поля, назначаемых, ваша функция GetClientNameById, если она вызывается одновременно, может видеть те поля, которые назначаются из разных вызовов TCP-вызова. Вы можете рассмотреть вопрос о синхронизации доступа к этому переменному опросу с использованием шлюза:

private readonly ReaderWriterLockSlim gateway = new ReaderWriterLockSlim(); 

, а затем при написании полей получить блокировку записи:

gateway.EnterWriteLock(); 
try 
{ 
    poll.A = reply1; 
    poll.B = reply2; 
    poll.C = reply3; 
    poll.D = reply4; 
    poll.E = DateTime.Now.ToString("HH:mm:ss.fff"); 
} 
finally 
{ 
    gateway.ExitWriteLock(); 
} 

и при чтении:

if (Id == "Poll") 
{ 
    gateway.EnterReadLock(); 
    try 
    { 
     Console.WriteLine("Reply: " + poll.A + " " + poll.B + " " + poll.C + " " + poll.D + " " + poll.E); 

     json = JsonConvert.SerializeObject(poll, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented }); 
    } 
    finally 
    { 
     gateway.ExitReadLock(); 
    } 
} 

Если вы не хотите использовать один и тот же экземпляр для обоих вызовов функций, вы можете сделать статическое поле poll так, чтобы оно было общим для всех экземпляров. Замечание о гоночном состоянии по-прежнему применяется, и вам необходимо правильно синхронизировать доступ к этому полю.

+0

Большое спасибо за ваши усилия. Я провел некоторое исследование, и похоже, что 'ReadWriterLockSlim' не рекомендуется для' async-await'. Поэтому вместо этого я использовал «СемафорСлим». – active92

Смежные вопросы