2017-06-21 46 views
0

我有一个目的服务,请执行下列操作:从意向字符串参数多个异步Ado.net SQL插入

  • 提取物,

  • 使用参数组成HTTP查询,

  • 使用异步任务和System.Net.Http执行它,

  • 解析接收JSON并提出一些字段值s到字符串sqlQuery,它应该将数据插入到sqlite数据库中,

  • 使用Ado.net执行sqlQuery(使用方法打开连接,然后关闭它)。

请注意,可能有几个意图调用服务,具有不同的PutExtra值。所以,活动告诉服务:“为City1加载信息”,“为City2加载信息”等。

UPD。这样做的目的服务代码:

public WeatherService() : base("WeatherService") 
    { 
    } 

    public string sqlQuery; 

    protected override async void OnHandleIntent(Android.Content.Intent intent) 
    { 

     // Get extras 
     string wsMode = intent.GetStringExtra("mode"); 
     string wsLocation = intent.GetStringExtra("location"); 
     string wsProvider = intent.GetStringExtra("provider"); 
     string wsUpdId = intent.GetStringExtra("upd_id"); 
     //string debugMsg = "INTENT_SERVICE_OUTPUT: Mode " + wsMode + ", location " + wsLocation + " , provider " + wsProvider; 
     //Console.WriteLine(debugMsg); 

     // Generate http string 
     string httpQuery = ""; 
     switch (wsProvider) 
     { 
      case "openweathermap": 
       httpQuery = "http://api.openweathermap.org/data/2.5/weather?&appid=1&units=metric&lang=ru"; //fake key here 
       if (wsMode == "code") { httpQuery = httpQuery + "&id=" + wsLocation; } 
       break; 
      default: 
       httpQuery = ""; 
       break; 
     } 

     // Get weather from the provider 
     dynamic results = await DataService.getDataFromService(httpQuery); 
     if (results["weather"] != null) 
     { 

      // Compose insert queries 
      if (sqlQuery == null) { sqlQuery = ""; Console.WriteLine("SQL QUERY FROM NULL TO EMPTY STRING"); } 
      sqlQuery = sqlQuery + 
       "INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " + 
        "SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["weather"][0]["description"] + 
        "',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentConditions';" + 
       "INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " + 
        "SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["main"]["temp"] + 
        "',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentTemperature';"; 
      Console.WriteLine(sqlQuery); 
     } 


    } 

    public override void OnDestroy() 
    { 

     // Insert data into databse 
     if (sqlQuery != null) { Sql.ExecQueryScalarOrNonQuery(sqlQuery, 0); Console.WriteLine("SQL_QUERY: INSERTED"); } else { Console.WriteLine("SQL_QUERY: EMPTY!!!"); } 

     // Update current view 
     // TODO 

     // End Service 
     base.OnDestroy(); 

所以,你可以看到,我试图声明一个名为sqlquery的字符串,并试图把它的一些数据插入。但问题是:要正确地问HTTP异步任务,我不得不让所有OnHandleIntent方法

保护覆盖异步无效OnHandleIntent()

因此,OnHandleIntent开始和的OnDestroy()immidiately推出,当sqlQuery仍然是空的!而就在几秒钟之前,OnHandleIntent-s(在我的例子中是两个)完成。因此,如何进行如下操作:在OnHandleIntent中,我们获得额外资讯,生成并启动http查询(使用异步任务而不是???),然后我们为db生成并保存插入内容(为了简单起见,让我们做到这一点在字符串sqlQuery;))。然后,当所有的OnHandleIntents准备就绪时,我们通过调用base.OnDestroy()来执行最后的sqlQuery(一次)并结束服务。提前Thnaks。

+0

发布实际码。描述中唯一明确的是有一个错误。异步执行与该问题有什么关系 - 除非您尝试使用相同的连接来运行多个命令(不)? –

+0

如果您想快速插入大量数据,请使用SqlBulkCopy。不要试图“平行”插入,你只会使事情变得更糟糕。在单个语句中发送100个插入可以比尝试并行执行100个插入快100倍,并最终彼此锁定。如果您使用具有100个值的“INSERT VALUES”语句,则速度会更快。虽然没有什么比SqlBulkCopy更好 - 它使用与bcp和“BULK INSERT”相同的批量导入机制。 –

+0

SqlBulkCopy使用* minimal *日志记录 - 而不是记录每个语句,它只记录修改后的数据页面。 –

回答

1

我决定改变方法声明

保护覆盖无效

和改写DataService类进行异步 - >同步如下:

public class DataService 
{ 
    public static object ReceivedData(string queryString) 
    { 

     // Exec the query 
     dynamic data = null; 
     using (HttpClient client = new HttpClient()) 
     { 
      var response = client.GetAsync(queryString).Result; 

      // If result is not null, deserialize json 
      if (response != null) 
      { 
       string json = response.Content.ReadAsStringAsync().Result; 
       data = JsonConvert.DeserializeObject(json); 
      } 

     } 

     // Return json result 
     return data; 

    } 
} 

在我的情况下,所有作品(同步)在一个intent服务线程中,然后成功地插入到本地sqlite数据库(在intentservice的OnDestroy()方法中。)