---
code: csharp_sdk_advanced
name: "进阶指南"
wikiToken: YGuuwcqPEi07zxkBBPScb6aJneh
parentWikiToken: HF7Dwv171ibMQtkmV1UcOhownPc
updateTime: 1745309874000
sourceUrl: https://docs-v2.thinkingdata.cn/?version=v5.0&lan=zh-CN&code=csharp_sdk_advanced
---
# 进阶指南

### 一、发送事件

在 SDK 初始化完成之后，您就可以进行数据埋点，收集用户的的行为信息。一般情况下普通事件即可满足业务场景需求，您也可以根据自己的实际业务场景使用首次、可更新等事件。

#### 1.1 普通事件

您可以调用 `Track` 来上传事件，建议您根据先前梳理的文档来设置事件的属性以及发送事件的条件，此处以用户购买某商品作为范例：

```
// 设置事件属性
Dictionary<string, object> properties = new Dictionary<string, object>();
// 字符串
properties.Add("product_name", "goods_name");
properties.Add("price", "123");
// account_id 和 distinct_id 必须至少设置其中一个
te.Track("accountId", "distinctId", "product_buy", properties);
```

#### 1.2 首次事件

首次事件是指针对某个设备或者其他维度的 ID，只会记录一次的事件。例如在一些场景下，您可能希望记录在某个设备上的激活事件，则可以用首次事件来上报数据。

```
// 上报首次事件，事件名为 device_activation
Dictionary<string, object> properties = new Dictionary<string, object>();
//设置事件属性
properties.Add("price", 35);
//account_id 和 distinct_id 必须至少设置其中一个,first_check_id的值不能为空
te.TrackFirst("accountId", "distinctId", "device_activation", "first_check_id", properties);
```

<!-- unsupported block: 34 -->

注意：由于在服务端完成对是否首次的校验，首次事件默认会延时 1 小时入库。

#### 1.3 可更新事件

您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID，并在创建可更新事件对象时传入。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。

```
// 上传可更新事件，事件名为 UPDATABLE_EVENT
// 事件属性 status 为 3, price 为 100
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("price", 100);
properties.Add("status", 3);
te.TrackUpdate("accountId", "distinctId", "UPDATABLE_EVENT", "event_id", properties);

// 上报后status 被更新为 5, price 不变
Dictionary<string, object> newProperties = new Dictionary<string, object>();
newProperties.Add("status", 5);
//account_id 和 distinct_id 必须至少设置其中一个，event_id不能为空
te.TrackUpdate("accountId", "distinctId", "UPDATABLE_EVENT", "event_id", properties);
```

#### 1.4 可重写事件

可重写事件与可更新事件类似，区别在于可重写事件会用最新的数据完全覆盖历史数据，从效果上看相当于删除前一条数据，并入库最新的数据。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。

```
// 上报可重写事件，事件名为 OVERWRITE_EVENT
// 上报后事件属性 status 为 3, price 为 100
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("price", 100);
properties.Add("status", 3);
//account_id 和 distinct_id 必须至少设置其中一个，event_id不能为空
te.TrackOverwrite("accountId", "distinctId", "OVERWRITE_EVENT", "event_id", properties);

// 上报后事件属性 status 被更新为 5, price 属性被删除
Dictionary<string, object> newProperties = new Dictionary<string, object>();
newProperties.Add("status", 5);
//account_id 和 distinct_id 必须至少设置其中一个，event_id不能为空
te.TrackOverwrite("accountId", "distinctId", "OVERWRITE_EVENT", "event_id", properties);
```

### 二、用户属性

AE 平台支持的用户属性设置API有: `UserSet`、`UserSetOnce`、`UserAdd`、

`UserUnset`、`UserDelete`、`UserAppend`、`UserUniqAppend`。

#### 2.1 UserSet

对于一般的用户属性，您可以调用 `UserSet` 来进行设置。使用该接口上传的属性将会覆盖原有的属性值，如果之前不存在该用户属性，则会新建该用户属性，类型与传入属性的类型一致，此处以设置用户名为例：

```
//此时username为TA
Dictionary<string, object> properties= new Dictionary<string, object>();
properties.Add("user_name","TA");
te.UserSet("accountId","distinctId", properties);
//此时userName为TE
Dictionary<string, object> newProperties= new Dictionary<string, object>();
newProperties.Add("user_name","TE");
//设置用户属性，accountId 和 distinctId 必须至少设置其中一个
te.UserSet("accountId","distinctId", newProperties);
```

#### 2.2 UserSetOnce

如果您要上传的用户属性只要设置一次，则可以调用`UserSetOnce`来进行设置，当该属性之前已经有值的时候，将会忽略这条信息，再以设置用户名为例：

```
//first_payment_time为2018-01-01 01:23:45.678
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("first_payment_time", "2018-01-01 01:23:45.678");
te.UserSetOnce("accountId", "distinctId", properties);
//first_payment_time仍然为2018-01-01 01:23:45.678
Dictionary<string, object> newProperties = new Dictionary<string, object>();
newProperties.Add("first_payment_time", "2018-12-31 01:23:45.678");
te.UserSetOnce("accountId", "distinctId", newProperties);
```

#### 2.3 UserAdd

当您要上传数值型的属性时，您可以调用`UserAdd`来对该属性进行累加操作，如果该属性还未被设置，则会赋值 0 后再进行计算，可传入负值，等同于相减操作。此处以累计付费金额为例：

```
//上传用户属性，此时"total_revenue"的值为30
Dictionary<string, object> properties = new Dictionary<string, object>();
properties.Add("total_revenue", 30);
te.UserAdd("accountId", "distinctId", properties);

//再次上传用户属性，此时"total_revenue"的值会累加为678
Dictionary<string, object> newProperties = new Dictionary<string, object>();
newProperties.Add("total_revenue", 648);
te.UserAdd("accountId", "distinctId", newProperties);
```

<!-- unsupported block: 34 -->

设置的属性key为字符串，Value 只允许为数值。

#### 2.4 UserAppend

您可以调用 `UserAppend` 对数组类型的用户属性进行追加操作。

```
Dictionary<string, object> dictionary = new Dictionary<string, object>();
List<string> list = new List<string>();
list.Add("ball");
dictionary.Add("user_list", list);
te.UserAppend("accountId", "distinctId", dictionary);
```

#### 2.5 UserUniqAppend

您可以调用 `UserUniqAppend` 对 数组类型的用户属性进行追加操作。调用 `UserUniqAppend` 接口会对追加的用户属性进行去重， `UserAppend` 接口不做去重，用户属性可存在重复。

```
//此时user_list的属性值为["apple"，"ball"]     
Dictionary<string, object> dictionary = new Dictionary<string, object>();
List<string> list = new List<string>();
list.Add("apple");
list.Add("ball");
dictionary.Add("user_list", list);
te.UserAppend("accountId", "distinctId", dictionary);

//此时user_list的属性值为["apple","apple","ball","cube"]
Dictionary<string, object> newDictionary = new Dictionary<string, object>();
List<string> newList = new List<string>();
newList.Add("apple");
newList.Add("cube");
newDictionary.Add("user_list", newList);
te.UserAppend("accountId", "distinctId", newDictionary);

//此时user_list的属性值为["apple"，"ball","cube"]
te.UserUniqAppend("accountId", "distinctId", newDictionary);
```

#### 2.6 UserUnset

当您要清空用户的用户属性值时，您可以调用`UserUnset`来对指定属性进行清空操作，如果该属性还未在集群中被创建，则`UserUnset`不会创建该属性

```
// 删除这个用户的某个属性 必须是string类型的集合，例如：
List<string> list = new List<string>();
list.Add("nickname");
list.Add("age");
te.UserUnSet("accountId", "distinctId", list);
```

<!-- unsupported block: 34 -->

user_unset: 的传入值为被清空属性的 Key 值。

#### 2.7 UserDelete

如果您要删除某个用户，可以调用`UserDelete`将这名用户删除，您将无法再查询该名用户的用户属性，但该用户产生的事件仍然可以被查询到，该操作可能产生不可逆的后果，请慎用

```
te.UserDelete("accountId", "distinctId");
```

### 三、其他功能

#### 3.1 TDBatchConsumer

::: warning 注意

当数据量过大或者网络异常时，有数据丢失的风险，不建议在正式环境中使用

:::

批量实时地向 AE 服务器传输数据，不需要搭配传输工具。

```
TDAnalytics te = new(new TDBatchConsumer("SERVER_URL", "APPID", true));
```

参数说明:

- `APPID`: 您的项目的 APPID，可通过在 AE 后台项目管理页面获取
- `SERVER_URL`: 数据上传的 URL
- 如果您对接的是云服务，填入: https://global-receiver-ta.thinkingdata.cn 
- 如果您使用私有化部署版本，请为数据采集地址绑定域名，并配置 HTTPS 证书：https://数据采集地址绑定域名
#### 3.2 定时刷新功能

默认情况下，SDK 只会根据当前的数据大小自动上报数据，您可以配置LogConfig参数开启定时提交数据的功能。

```
using ThinkingData.Analytics

 TDLoggerConsumer.TDConfig config = new TDLoggerConsumer.TDConfig();
 //设置每3S提交数据一次，默认是10S
 config.BatchSec = 3;

 TDAnalytics te = new(new TDLoggerConsumer("LOG_DIRECTORY", config));
```
