附上设计代码:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyTcpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyBehavior" name="VCFService.Service1">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8081//"/>
</baseAddresses>
</host>
<endpoint address="S1" binding="netTcpBinding" bindingConfiguration="MyTcpBinding" contract="VCFService.IService1"></endpoint>
<endpoint address="mex111" binding="netTcpBinding" contract="IMetadataExchange" bindingConfiguration="MyTcpBinding" ></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="6553600"/>
</behavior>
<behavior name="ThrottledBehavior">
<serviceThrottling maxConcurrentCalls="5000" maxConcurrentSessions="5000" maxConcurrentInstances="5000" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
<runtime>
<gcServer enabled="true" />
</runtime>
<appSettings>
<add key="server" value="127.0.0.1" />
<add key="DataBaseName" value="dsportmis" />
<add key="DBUserId" value="sa" />
<add key="DBPassWord" value="12345" />
</appSettings>
</configuration>
服务端源码:
const int SleepTime = 100;
public ServiceHost _serviceHost = null;
private Thread _thread;
private bool _isRunning;
public ThreadServiceHost(Type serviceType)
{
try
{
_serviceHost = new ServiceHost(serviceType);
_thread = new Thread(RunService);
_thread.Start();
}
catch (System.Exception ex)
{
ShwMsgForView.ShwMsgforView(Comm.memoEdit, "启动服务失败......." + ex.ToString());
}
}
void RunService()
{
try
{
_serviceHost.Open();
_isRunning = true;
VCFService.ShwMsgForView.ShwMsgforView(Comm.memoEdit, "服务启动完成.......");
//while (_isRunning)
//{
// Thread.Sleep(SleepTime);
//}
//_serviceHost.Close();
//((IDisposable)_serviceHost).Dispose();
}
catch (Exception ex)
{
if (_serviceHost != null)
_serviceHost.Abort();
ShwMsgForView.ShwMsgforView(Comm.memoEdit, "启动服务失败......." + ex.ToString());
//throw ex;
}
}
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService1,IDisposable
{
public string GetXml(CurUser user, string DtSql)
{
Thread.Sleep(100);
Func<CurUser,string, string> method = GetXml1;
IAsyncResult cookie = method.BeginInvoke(user, DtSql, null, null);
ShwMsgForView.ShwMsgforView(Comm.memoEdit, DtSql);
string result = method.EndInvoke(cookie);
return result;
}
public string GetXml1(CurUser user, string DtSql)
{
using (DbHelper dbhelper = new DbHelper())
{
Thread.Sleep(100);
return dbhelper.GetXml(user, DtSql);
}
}
public string GetXml(CurUser user, string DtSql)
{
try
{
DataSet dtResult;
string strResult;
StringBuilder strSql = new StringBuilder();
strSql.Append(DtSql);
dtResult = GetDataSetByProc(user, CommandType.Text, strSql.ToString());
return strResult=XmlUtil.Serializer(typeof(DataTable), dtResult.Tables[0]);
}
catch (System.Exception ex)
{
Comm.OuntPutLog("检索数据'" + DtSql + "'发生错误:" + ex.ToString());
throw new FaultException(ex.ToString());
}
}
public DataSet GetDataSetByProc(CurUser user, CommandType type, string procName, params SqlParameter[] parameters)//在用,查询表
{
if (user == null)
{
user = new CurUser();
}
ShwMsgForView.ShwMsgforView(Comm.memoEdit, user.UserName + "(" + user.IPAddress + ")" + "用户执行:" + procName);
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = procName;
cmd.CommandType = type;
cmd.CommandTimeout = timeout;
cmd.Parameters.AddRange(parameters);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
using (DataSet ds = new DataSet())
{
try
{
da.Fill(ds);
conn.Close();
return ds;
}
catch (System.Exception ex)
{
throw new FaultException(ex.ToString());
}
}
}
}
}
}
public class ShwMsgForView
{
delegate void ShwMsgforViewCallBack(DevExpress.XtraEditors.MemoEdit memoEdit1, string text);
public static void ShwMsgforView(DevExpress.XtraEditors.MemoEdit memoEdit1, string text)
{
Comm.OuntPutLog(text);
if (memoEdit1==null)
{
return;
}
if (memoEdit1.InvokeRequired)
{
ShwMsgforViewCallBack shwMsgforViewCallBack = ShwMsgforView;
memoEdit1.Invoke(shwMsgforViewCallBack, new object[] { memoEdit1, text });
}
else
{
string Strlog = "\r\n===========" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "===========\r\n" + text + "\r\n";
memoEdit1.Text = Strlog + memoEdit1.Text;
if (memoEdit1.Lines.Length>=5000)
{
memoEdit1.Text = "";
}
}
}
}
public static void OuntPutLog(string text, Boolean IsOpen = false)//操作日志,最新日志放在最前面
{
try
{
string Strlog = "\r\n===========" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "===========\r\n" + text + "\r\n";
string strFilePath = sPath + "\\Log\\OptLog" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
File.AppendAllText(strFilePath, "", System.Text.Encoding.Default);
string strOldText = File.ReadAllText(strFilePath, System.Text.Encoding.Default);
File.WriteAllText(strFilePath, Strlog, System.Text.Encoding.Default);
File.AppendAllText(strFilePath, strOldText, System.Text.Encoding.Default);
if (IsOpen)
{
try
{
Process p = new Process();
p.StartInfo.FileName = strFilePath;
p.Start();
}
catch (System.Exception ex)
{
throw new FaultException(ex.ToString());
}
}
}
catch (System.Exception ex)
{
//ErrorLogWrite("写操作日志错误:" + ex.ToString());
}
}
12 个解决方案
#1
为什么选择winform 作为wcf的宿主呢?
#2
单看你的 GetXml 方法吧:
1. 写 Sleep 是动了什么歪脑筋?故意阻塞当前程序是要干什么?一个人请求阻塞100毫秒,10个请求就阻塞1秒?
2. Func<.....> 那个是委托,那个不叫 method,method是method、委托是委托,二者是不同的概念。这就好像一个是“祖国”,另一个是“海外殖民地”,是两回事。你可以起一个雷人的名字(就好像设计模式那样),但是不要为变量起一个张冠李戴容易引起误会的名字。
3. 你的多线程编程完全是无意义的。你用了多线程异步的语法,来模拟一个同步操作流程。你在执行了 BeginInvoke 之后,接下来的代码操作就阻塞在那里等待 EndInvoke 的完成,这种东西可能只在 msdn 上给你讲解、演示最低级的编程语法时才有的(幼儿园的编程方式)。真正的多线程编程设计是“回调”式的,在 BeginInvoke 之后绝对不会去阻塞地等待什么 EndInvoke,而是直接就结束了 GetXml 方法了!EndInvoke方法应该放到 BeginInvoke 所注册的回调方法中的第一句去执行,然后这个GetXml再调用客户程序所要的回调方法。
也就是说,一个异步回调的 GetXml 方法从接口定义上就会是这样
在.net4.5以上版本,发明了一种 async/await 语法,这用来迎合那些满脑子只有同步方法语法的人。但是这显然是逻辑上比较复杂的,对使用者的要求比使用回调方式更高。否则,假设真的是一个只知道同步调用的人来使用这个新语法,那么这个语法就成了笑柄了,因为一个人没有实现非常充分地理解异步回调设计,又怎么会理解 asyn/await 语法?所以那些说“这个语法可以使程序员使用同步调用语法来编写异步多线程程序”其实是个败笔、是个谎言。程序员一旦编写代码、一旦调试,就知道不理解自己的代码了。
没有设计异步回调代码的习惯,怎么可能知道什么叫做多线程并发?
1. 写 Sleep 是动了什么歪脑筋?故意阻塞当前程序是要干什么?一个人请求阻塞100毫秒,10个请求就阻塞1秒?
2. Func<.....> 那个是委托,那个不叫 method,method是method、委托是委托,二者是不同的概念。这就好像一个是“祖国”,另一个是“海外殖民地”,是两回事。你可以起一个雷人的名字(就好像设计模式那样),但是不要为变量起一个张冠李戴容易引起误会的名字。
3. 你的多线程编程完全是无意义的。你用了多线程异步的语法,来模拟一个同步操作流程。你在执行了 BeginInvoke 之后,接下来的代码操作就阻塞在那里等待 EndInvoke 的完成,这种东西可能只在 msdn 上给你讲解、演示最低级的编程语法时才有的(幼儿园的编程方式)。真正的多线程编程设计是“回调”式的,在 BeginInvoke 之后绝对不会去阻塞地等待什么 EndInvoke,而是直接就结束了 GetXml 方法了!EndInvoke方法应该放到 BeginInvoke 所注册的回调方法中的第一句去执行,然后这个GetXml再调用客户程序所要的回调方法。
也就是说,一个异步回调的 GetXml 方法从接口定义上就会是这样
public void GetXml(CurUser user, string DtSql, Action<string> callback)这样一个异步回调格式的方法,才可以承载其多线程并发操作之实际内涵。
{
.......
}
在.net4.5以上版本,发明了一种 async/await 语法,这用来迎合那些满脑子只有同步方法语法的人。但是这显然是逻辑上比较复杂的,对使用者的要求比使用回调方式更高。否则,假设真的是一个只知道同步调用的人来使用这个新语法,那么这个语法就成了笑柄了,因为一个人没有实现非常充分地理解异步回调设计,又怎么会理解 asyn/await 语法?所以那些说“这个语法可以使程序员使用同步调用语法来编写异步多线程程序”其实是个败笔、是个谎言。程序员一旦编写代码、一旦调试,就知道不理解自己的代码了。
没有设计异步回调代码的习惯,怎么可能知道什么叫做多线程并发?
#3
随便一个 javascript 程序员都知道异步回调的机制。例如使用 jQuery 中的 jQuery.ajax 函数等等。因此他们的“感觉上”就学会了编写异步回调的程序。而异步回调程序,就为其后台承载多线程并发执行流程提供了基本的保证。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
#4
看您给所有人的回复,都只批评哪里写的有问题,我自学的c#,看您这种专家的批评我依然不懂得改,请您在批评的同时告诉我应该怎么写才是对的
#5
使用iis的时候我单客户端重复执行查询40次后会提示应答超时,唉(๑◕︵◕๑)
#6
p哥建议不建议用async/await呢?我是把它当做架构(c端的web架构)的基础设施在用
#7
很多时候要讲明一个概念,比如这种线程问题,需要一篇或者几篇文章的篇幅来讲,不是csdn上几句话能讲明白的。
你可以到博客园上看几篇讲线程的文章。p哥的话高度太高,可以指路,细节还得你自己去研究
#8
p哥建议不建议用async/await呢?我是把它当做架构(c端的web架构)的基础设施在用
不要抠这个字眼儿。我是说明“为什么有的人换了好几只越来越贵的笔、结果仍然写不出好文章来”的道理。
这里,先要学会异步回调 设计,没有这个基础就不知道内部机制,那么学 async/await 就更多盲从性了。
#9
正因为是跟自认为已经能堆砌一大堆无关“技术”的人、被技术害惨了的人来说明一个浅显的道理,所以比较费时间。因为他过去2、3年可能都没有学过基础,重新学习基本概念会觉得很不习惯。
#10
这里就是非常适宜的功能点,正好是针对 lz 具体问题来重点说明,我不知道这个“重点说明”跟博客园有什么替代关系。如果有比较针对性的文章,不管是不是博客园上的文章,欢迎贴出链接来。但是当你谈论一个服装设计技术时你不能用一句“大街上批发衣服的地方有很多啊”来说明,当你谈论写一篇畅销小说时不能用一句“网络上垃圾下载站可以下载5G的小说啊”来说明。
这里就是针对当前帖子的重点错误,进行一次重点解决。
这里就是针对当前帖子的重点错误,进行一次重点解决。
#11
有没有人能直接告诉我我错的地方,应该怎么修正
#12
wcf的接口本身就是多线程的。。。楼主你只需要把那些画蛇添足的多线程代码删除掉就好了
#1
为什么选择winform 作为wcf的宿主呢?
#2
单看你的 GetXml 方法吧:
1. 写 Sleep 是动了什么歪脑筋?故意阻塞当前程序是要干什么?一个人请求阻塞100毫秒,10个请求就阻塞1秒?
2. Func<.....> 那个是委托,那个不叫 method,method是method、委托是委托,二者是不同的概念。这就好像一个是“祖国”,另一个是“海外殖民地”,是两回事。你可以起一个雷人的名字(就好像设计模式那样),但是不要为变量起一个张冠李戴容易引起误会的名字。
3. 你的多线程编程完全是无意义的。你用了多线程异步的语法,来模拟一个同步操作流程。你在执行了 BeginInvoke 之后,接下来的代码操作就阻塞在那里等待 EndInvoke 的完成,这种东西可能只在 msdn 上给你讲解、演示最低级的编程语法时才有的(幼儿园的编程方式)。真正的多线程编程设计是“回调”式的,在 BeginInvoke 之后绝对不会去阻塞地等待什么 EndInvoke,而是直接就结束了 GetXml 方法了!EndInvoke方法应该放到 BeginInvoke 所注册的回调方法中的第一句去执行,然后这个GetXml再调用客户程序所要的回调方法。
也就是说,一个异步回调的 GetXml 方法从接口定义上就会是这样
在.net4.5以上版本,发明了一种 async/await 语法,这用来迎合那些满脑子只有同步方法语法的人。但是这显然是逻辑上比较复杂的,对使用者的要求比使用回调方式更高。否则,假设真的是一个只知道同步调用的人来使用这个新语法,那么这个语法就成了笑柄了,因为一个人没有实现非常充分地理解异步回调设计,又怎么会理解 asyn/await 语法?所以那些说“这个语法可以使程序员使用同步调用语法来编写异步多线程程序”其实是个败笔、是个谎言。程序员一旦编写代码、一旦调试,就知道不理解自己的代码了。
没有设计异步回调代码的习惯,怎么可能知道什么叫做多线程并发?
1. 写 Sleep 是动了什么歪脑筋?故意阻塞当前程序是要干什么?一个人请求阻塞100毫秒,10个请求就阻塞1秒?
2. Func<.....> 那个是委托,那个不叫 method,method是method、委托是委托,二者是不同的概念。这就好像一个是“祖国”,另一个是“海外殖民地”,是两回事。你可以起一个雷人的名字(就好像设计模式那样),但是不要为变量起一个张冠李戴容易引起误会的名字。
3. 你的多线程编程完全是无意义的。你用了多线程异步的语法,来模拟一个同步操作流程。你在执行了 BeginInvoke 之后,接下来的代码操作就阻塞在那里等待 EndInvoke 的完成,这种东西可能只在 msdn 上给你讲解、演示最低级的编程语法时才有的(幼儿园的编程方式)。真正的多线程编程设计是“回调”式的,在 BeginInvoke 之后绝对不会去阻塞地等待什么 EndInvoke,而是直接就结束了 GetXml 方法了!EndInvoke方法应该放到 BeginInvoke 所注册的回调方法中的第一句去执行,然后这个GetXml再调用客户程序所要的回调方法。
也就是说,一个异步回调的 GetXml 方法从接口定义上就会是这样
public void GetXml(CurUser user, string DtSql, Action<string> callback)这样一个异步回调格式的方法,才可以承载其多线程并发操作之实际内涵。
{
.......
}
在.net4.5以上版本,发明了一种 async/await 语法,这用来迎合那些满脑子只有同步方法语法的人。但是这显然是逻辑上比较复杂的,对使用者的要求比使用回调方式更高。否则,假设真的是一个只知道同步调用的人来使用这个新语法,那么这个语法就成了笑柄了,因为一个人没有实现非常充分地理解异步回调设计,又怎么会理解 asyn/await 语法?所以那些说“这个语法可以使程序员使用同步调用语法来编写异步多线程程序”其实是个败笔、是个谎言。程序员一旦编写代码、一旦调试,就知道不理解自己的代码了。
没有设计异步回调代码的习惯,怎么可能知道什么叫做多线程并发?
#3
随便一个 javascript 程序员都知道异步回调的机制。例如使用 jQuery 中的 jQuery.ajax 函数等等。因此他们的“感觉上”就学会了编写异步回调的程序。而异步回调程序,就为其后台承载多线程并发执行流程提供了基本的保证。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
#4
随便一个 javascript 程序员都知道异步回调的机制。例如使用 jQuery 中的 jQuery.ajax 函数等等。因此他们的“感觉上”就学会了编写异步回调的程序。而异步回调程序,就为其后台承载多线程并发执行流程提供了基本的保证。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
#5
为什么选择winform 作为wcf的宿主呢?
#6
单看你的 GetXml 方法吧:
1. 写 Sleep 是动了什么歪脑筋?故意阻塞当前程序是要干什么?一个人请求阻塞100毫秒,10个请求就阻塞1秒?
2. Func<.....> 那个是委托,那个不叫 method,method是method、委托是委托,二者是不同的概念。这就好像一个是“祖国”,另一个是“海外殖民地”,是两回事。你可以起一个雷人的名字(就好像设计模式那样),但是不要为变量起一个张冠李戴容易引起误会的名字。
3. 你的多线程编程完全是无意义的。你用了多线程异步的语法,来模拟一个同步操作流程。你在执行了 BeginInvoke 之后,接下来的代码操作就阻塞在那里等待 EndInvoke 的完成,这种东西可能只在 msdn 上给你讲解、演示最低级的编程语法时才有的(幼儿园的编程方式)。真正的多线程编程设计是“回调”式的,在 BeginInvoke 之后绝对不会去阻塞地等待什么 EndInvoke,而是直接就结束了 GetXml 方法了!EndInvoke方法应该放到 BeginInvoke 所注册的回调方法中的第一句去执行,然后这个GetXml再调用客户程序所要的回调方法。
也就是说,一个异步回调的 GetXml 方法从接口定义上就会是这样public void GetXml(CurUser user, string DtSql, Action<string> callback)这样一个异步回调格式的方法,才可以承载其多线程并发操作之实际内涵。
{
.......
}
在.net4.5以上版本,发明了一种 async/await 语法,这用来迎合那些满脑子只有同步方法语法的人。但是这显然是逻辑上比较复杂的,对使用者的要求比使用回调方式更高。否则,假设真的是一个只知道同步调用的人来使用这个新语法,那么这个语法就成了笑柄了,因为一个人没有实现非常充分地理解异步回调设计,又怎么会理解 asyn/await 语法?所以那些说“这个语法可以使程序员使用同步调用语法来编写异步多线程程序”其实是个败笔、是个谎言。程序员一旦编写代码、一旦调试,就知道不理解自己的代码了。
没有设计异步回调代码的习惯,怎么可能知道什么叫做多线程并发?
p哥建议不建议用async/await呢?我是把它当做架构(c端的web架构)的基础设施在用
#7
看您给所有人的回复,都只批评哪里写的有问题,我自学的c#,看您这种专家的批评我依然不懂得改,请您在批评的同时告诉我应该怎么写才是对的 随便一个 javascript 程序员都知道异步回调的机制。例如使用 jQuery 中的 jQuery.ajax 函数等等。因此他们的“感觉上”就学会了编写异步回调的程序。而异步回调程序,就为其后台承载多线程并发执行流程提供了基本的保证。
所以由此可见,许多.net 编程者在这个方面的平均入门知识水平是不如学过一点 jQuery 的编程者的知识水平的。对于异步编程、多线程并发程序设计,缺乏基础知识。
在 javascript 最新版本中也引入了 async/await 语法,可能再过2年就会在许多 js 开源插件中看到这种语法。但是 jQuery 等等已经流行了很多年,程序员都习惯写异步回调的代码,而且甚至都“写腻了”。
可是大多数 .net 程序员并没有写腻,而是还没有基本概念。
很多时候要讲明一个概念,比如这种线程问题,需要一篇或者几篇文章的篇幅来讲,不是csdn上几句话能讲明白的。
你可以到博客园上看几篇讲线程的文章。p哥的话高度太高,可以指路,细节还得你自己去研究
#8
p哥建议不建议用async/await呢?我是把它当做架构(c端的web架构)的基础设施在用
不要抠这个字眼儿。我是说明“为什么有的人换了好几只越来越贵的笔、结果仍然写不出好文章来”的道理。
这里,先要学会异步回调 设计,没有这个基础就不知道内部机制,那么学 async/await 就更多盲从性了。
#9
正因为是跟自认为已经能堆砌一大堆无关“技术”的人、被技术害惨了的人来说明一个浅显的道理,所以比较费时间。因为他过去2、3年可能都没有学过基础,重新学习基本概念会觉得很不习惯。
#10
这里就是非常适宜的功能点,正好是针对 lz 具体问题来重点说明,我不知道这个“重点说明”跟博客园有什么替代关系。如果有比较针对性的文章,不管是不是博客园上的文章,欢迎贴出链接来。但是当你谈论一个服装设计技术时你不能用一句“大街上批发衣服的地方有很多啊”来说明,当你谈论写一篇畅销小说时不能用一句“网络上垃圾下载站可以下载5G的小说啊”来说明。
这里就是针对当前帖子的重点错误,进行一次重点解决。
这里就是针对当前帖子的重点错误,进行一次重点解决。
#11
有没有人能直接告诉我我错的地方,应该怎么修正
#12
wcf的接口本身就是多线程的。。。楼主你只需要把那些画蛇添足的多线程代码删除掉就好了