我正在异步发送HTTP请求,并且我想以某种方式将局部变量传递给该任务的完成处理程序。问题是变量在执行dataTask之后就在更改,因此我需要复制该变量。
protected void BindSubmitTo()
{
try
{
SqlDataReader dr;
using (SqlCommand cmd = new SqlCommand("select D.EmpId_Int, E.EmpName_vc from Dept_PM_HOD_List D Left Join Gen_Employee E on D.EmpId_Int = E.EmpId_Int where D.LCode_Int = @intDeptId and D.EmpId_Int<> @intEmpId and(E.EmpType_vc ='PM' or(E.EmpType_vc = 'HOD'))", Cnn))
cmd.Parameters.AddWithValue("@intDeptId", LocId.Text);
cmd.Parameters.AddWithValue("@intEmpId", EmpID.Text);
cmd.CommandType = CommandType.Text;
Cnn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
Submit_dd.DataSource = dr;
Submit_dd.DataTextField = "EmpName_vc";
Submit_dd.DataValueField = "EmpId_Int";
Submit_dd.DataBind();
Submit_dd.Items.Insert(0, new ListItem("--Select--", "0"));
}
Cnn.Close();
}
}
</div><br /><br />
<div class="form-group col-sm-1">
<asp:DropDownList ID="Submit_dd" placeholder="" Cssclass="form-control" runat="server"></asp:DropDownList>
<asp:Label ID="sublbl_error" Text="" ForeColor="Red" runat="server" ></asp:Label>
</div>
</div>
<div>
<asp:GridView ID="gridview_TS"
CssClass="table table-striped table-hover"
runat="server"
GridLines="None"
AutoGenerateColumns="False"
AllowPaging="True"
AllowSorting="True"
PageSize="20"
DataKeyNames="EmpId_int,ProjectCode_int" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="Chk_Int" HeaderText="Chk_Int" SortExpression="Chk_Int" Visible="False" />
<asp:TemplateField HeaderText="">
<ItemTemplate>
<asp:CheckBox ID="cbSelect" CssClass="form-control" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="EmpId_Int" HeaderText="EmpId_Int" />
<asp:BoundField DataField="TSDate_dt" HeaderText="Date" SortExpression="TSDate_dt" />
<asp:BoundField DataField="ProjectCode_int" HeaderText="Project Code" SortExpression="ProjectCode_int" />
<asp:BoundField DataField="ProjectName_vc" HeaderText="Project Name" SortExpression="ProjectName_vc" />
<asp:BoundField DataField="CCode_Int" HeaderText="CCode_Int" Visible="False" />
<asp:BoundField DataField="CostCode_vc" HeaderText="Cost Code Group" SortExpression="CostCode_vc" />
<asp:BoundField DataField="CCode_vc" HeaderText="Cost Code Description" SortExpression="CCode_vc" />
<asp:BoundField DataField="TSRhours_nu" HeaderText="Reg. Hours" SortExpression="TSRhours_nu" />
<asp:BoundField DataField="TSOhours_nu" HeaderText="OT. Hours" SortExpression="TSOhours_nu" />
<asp:BoundField DataField="JobDescp_vc" HeaderText="Job Narration" SortExpression="JobDescp_vc" />
<asp:BoundField DataField="EmpName_vc" HeaderText="Submit To" SortExpression="True" />
<asp:BoundField DataField="SubmitTo_Int" HeaderText="SubmitTo_Int" Visible="False" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TSMSConnectionString %>"
SelectCommand="SELECT S.EmpId_Int, T.Chk_Int, T.TSDate_dt, T.ProjectCode_Int, P.ProjectName_vc,
T.CCode_Int, C.CostCode_vc, C.CCode_vc, T.TSRhours_nu, T.TSOhours_nu, T.JobDescp_vc, E.EmpName_vc,
T.SubmitTo_Int FROM TSHistory T LEFT JOIN Sec_Users S ON T.EmpId_Int= S.EmpId_Int
LEFT JOIN Gen_ProjectList P ON T.ProjectCode_Int = P.ProjectCode_Int
LEFT JOIN Gen_CCList C ON T.CCode_Int= C.CCode_Int LEFT JOIN Gen_Employee E
ON T.EmpId_Int = E.EmpId_Int WHERE (S.UserId_vc = @userId) AND (T.SubmitTo_Int = 0) ORDER BY T.TSDate_dt DESC ">
<SelectParameters>
<asp:SessionParameter DefaultValue ="" Name="userId" SessionField="user" Type="string" />
</SelectParameters>
</asp:SqlDataSource>
</div>
<div class="btn btm-default btn-block" style="width:100%">
<asp:Button ID="create_TS" runat="server" Text="Create" class="btn btn-success mr-5" OnClick="btnCreate_click" />
<asp:Button ID="delete_TS" runat="server" Text="Delete" class="btn btn-danger mr-5" />
<asp:Button ID="update_TS" runat="server" Text="Update" class="btn btn-info mr-5" />
<asp:Button ID="clear_TS" runat="server" Text="Clear" CssClass="btn btn-outline-light mr-5" />
</div>
这当然会打印增加的值(N次)。如何在初始化任务期间修复var?
答案 0 :(得分:2)
为此,DispatchGroup
是推荐的API,例如
var neededVariable = 1
let group = DispatchGroup()
let session = URLSession.shared
for _ in 0...10 {
group.enter()
let urlS = "https://sub2pewdiepie.com/subscribe.php?param1=123"
let url = URL(string: urlS.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)!
let task = session.dataTask(with: url, completionHandler: { data, response, error in
defer(group.leave())
if let error = error { print(error); return }
do {
neededVariable += 1
print(neededVariable)
} catch let error { print(error.localizedDescription) }
})
task.resume()
}
group.notify(queue: DispatchQueue.main) {
print("notify", neededVariable)
}
答案 1 :(得分:0)
尝试使用一些工具进行线程管理。例如:信号量。
首先在数据任务开始之前声明信号量:
let semaphore = DispatchSemaphore(value: 1)
然后重构数据任务代码:
let task = session.dataTask(with: request as URLRequest, completionHandler:
{ [weak self] data, response, error in // don't forget to use weak self to avoid memory leaks
guard let `self` = self else { return }
self.semaphore.wait()
guard error = nil else {
self.semaphore.signal()
return
}
guard let data = data else {
self.semaphore.signal()
return
}
// you should not use do block here
//do {
print(self.neededVariable)
//} catch let error { print(error.localizedDescription) }
self.semaphore.signal()
})
当然:
task.resume()
semaphore.wait()
neededVariable = 2
希望它有所帮助!